+Mon Jan 20 17:59:51 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (standard_conversion): Handle getting references. Tack
+ on RVALUE_CONV here. Do it for non-class types, too.
+ (reference_binding): Pass references to standard_conversion.
+ (implicit_conversion): Likewise.
+ (add_builtin_candidate): Disable one ?: kludge.
+ (convert_like): Handle RVALUE_CONVs for non-class types.
+ (joust): Disable the other ?: kludge.
+
+Mon Jan 20 14:53:13 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (init_decl_processing): Add code to build up common
+ function types beforehand, to avoid creation then removal of
+ things already in the hash table.
+
+Mon Jan 20 14:43:49 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (finish_function): Also zero out DECL_INCOMING_RTL for
+ the arguments.
+
+ * error.c (dump_expr, TEMPLATE_CONST_PARM): Don't require
+ current_template_parms.
+
+Fri Jan 17 10:25:42 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (lookup_field): Don't return a function, check want_type.
+
+Thu Jan 16 18:14:35 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * init.c (build_new): Make sure PLACEMENT has a type.
+
+Thu Jan 16 17:40:28 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_new): Support new (nothrow).
+
+Wed Jan 15 12:38:14 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_decl): Also do push_to_top_level before setting
+ up DECL_INITIAL.
+
+ * cp-tree.h (PARM_DEFAULT_FROM_TEMPLATE): New macro.
+ * pt.c (tsubst): Defer instantiation of default args.
+ * call.c (build_over_call): Until here.
+
+Wed Jan 15 10:08:10 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * search.c (lookup_field): Make sure we have an
+ IDENTIFIER_CLASS_VALUE before we try to return it.
+
+Thu Jan 9 07:19:01 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (build_method_call): Delete unused var PARM.
+ (build_overload_call_real): Likewise.
+ (build_object_call): Delete unused var P.
+ (build_new_op): Likewise.
+ * decl.c (builtin_type_tdescs_{arr, len, max}): #if 0 out static
+ var definitions, which are never used.
+ (shadow_tag): Delete unused var FN.
+ * expr.c (cplus_expand_expr): Delete unused var ORIGINAL_TARGET.
+ * init.c (build_new): Delete unused var ALLOC_TEMP.
+ * method.c (hack_identifier): Delete unused var CONTEXT.
+ (do_build_copy_constructor): Delete unused var NAME.
+ (synthesize_method): Delete unused var BASE.
+ * pt.c (lookup_template_class): Delete unused var CODE_TYPE_NODE.
+ * rtti.c (build_headof): Delete unused var VPTR.
+ (get_typeid): Delete unused var T.
+ * typeck.c (build_conditional_expr): Delete unused vars ORIG_OP1
+ and ORIG_OP2.
+ (build_ptrmemfunc): Delete unused vars U and NINDEX.
+ * typeck2.c (build_functional_cast): Delete unused var BINFO.
+
+Wed Jan 8 13:09:54 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (lookup_field): Use IDENTIFIER_CLASS_VALUE to look up
+ things in a type being defined.
+ * decl.c (finish_enum): Reverse the values so that they are in
+ the correct order.
+
+ * pt.c (instantiate_class_template): Don't initialize
+ BINFO_BASETYPES until the vector is filled out.
+ (unify): Don't abort on conflicting bindings, just fail.
+ (instantiate_decl): Do push_tinst_level before any tsubsting.
+
+ * method.c (build_overload_value): Handle getting a
+ TEMPLATE_CONST_PARM for a pointer.
+
+Tue Jan 7 14:00:58 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (expand_member_init): Don't give 'not a base' error for
+ templates.
+
+ * pt.c (instantiate_decl): Call import_export_decl later.
+
+ * pt.c (instantiate_class_template): Return a value.
+
+ * parse.y (extension): New rule for __extension__.
+ (extdef, unary_expr, decl, component_decl): Use it.
+
+Tue Jan 7 09:20:28 1997 Mike Stump <mrs@cygnus.com>
+
+ * class.c (base_binfo): Remove unused base_has_virtual member.
+ (finish_base_struct): Likewise.
+ (finish_struct_1): Likewise.
+
+Tue Dec 31 20:25:50 1996 Mike Stump <mrs@cygnus.com>
+
+ * search.c (expand_upcast_fixups): Fix bogus code generation
+ problem where the generated code uses the wrong index into the
+ runtime built vtable on the stack. Old code could clobber random
+ stack values.
+
+Tue Dec 31 15:16:56 1996 Mike Stump <mrs@cygnus.com>
+
+ * init.c (perform_member_init): Make sure the partial EH cleanups
+ live on the function_obstack.
+
Fri Dec 27 10:31:40 1996 Paul Eggert <eggert@twinsun.com>
* Make-lang.in (g++spec.o): Don't use $< with an explicit target;
{
register tree function, fntype, value_type;
register tree basetype, save_basetype;
- register tree baselink, result, parmtypes, parm;
+ register tree baselink, result, parmtypes;
tree last;
int pass;
tree access = access_public_node;
int require_complete;
{
/* must check for overloading here */
- tree functions, function, parm;
+ tree functions, function;
tree parmtypes, last;
register tree outer;
int length;
return t;
}
+tree
+strip_top_quals (t)
+ tree t;
+{
+ if (TREE_CODE (t) == ARRAY_TYPE)
+ return t;
+ return TYPE_MAIN_VARIANT (t);
+}
+
/* Returns the standard conversion path (see [conv]) from type FROM to type
TO, if any. For proper handling of null pointer constants, you must
also pass the expression EXPR to convert from. */
{
enum tree_code fcode, tcode;
tree conv;
+ int fromref = 0;
+
+ if (TREE_CODE (to) == REFERENCE_TYPE)
+ to = TREE_TYPE (to);
+ if (TREE_CODE (from) == REFERENCE_TYPE)
+ {
+ fromref = 1;
+ from = TREE_TYPE (from);
+ }
+ to = strip_top_quals (to);
+ from = strip_top_quals (from);
fcode = TREE_CODE (from);
tcode = TREE_CODE (to);
conv = build1 (IDENTITY_CONV, from, expr);
- if (from == to)
- return conv;
-
if (fcode == FUNCTION_TYPE)
{
from = build_pointer_type (from);
fcode = TREE_CODE (from);
conv = build_conv (LVALUE_CONV, from, conv);
}
+ else if (fromref || (expr && real_lvalue_p (expr)))
+ conv = build_conv (RVALUE_CONV, from, conv);
+
+ if (from == to)
+ return conv;
if ((tcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (to))
&& expr && null_ptr_cst_p (expr))
return conv;
}
-tree
-strip_top_quals (t)
- tree t;
-{
- if (TREE_CODE (t) == ARRAY_TYPE)
- return t;
- return TYPE_MAIN_VARIANT (t);
-}
-
/* Returns the conversion path from type FROM to reference type TO for
purposes of reference binding. For lvalue binding, either pass a
reference type to FROM or an lvalue expression to EXPR.
an lvalue and a temporary. Should it? */
tree
-reference_binding (rto, from, expr, flags)
- tree rto, from, expr;
+reference_binding (rto, rfrom, expr, flags)
+ tree rto, rfrom, expr;
int flags;
{
tree conv;
int lvalue = 1;
tree to = TREE_TYPE (rto);
+ tree from = rfrom;
if (TREE_CODE (from) == REFERENCE_TYPE)
from = TREE_TYPE (from);
if (! conv)
{
- conv = standard_conversion
- (TYPE_MAIN_VARIANT (to), strip_top_quals (from), expr);
+ conv = standard_conversion (to, rfrom, expr);
if (conv)
{
conv = build_conv (REF_BIND, rto, conv);
- /* Bind directly to a base subobject of a class rvalue. */
+ /* Bind directly to a base subobject of a class rvalue. Do it
+ after building the conversion for proper handling of ICS_RANK. */
if (TREE_CODE (TREE_OPERAND (conv, 0)) == BASE_CONV)
TREE_OPERAND (conv, 0) = TREE_OPERAND (TREE_OPERAND (conv, 0), 0);
}
if (TREE_CODE (to) == REFERENCE_TYPE)
conv = reference_binding (to, from, expr, flags);
else
- conv = standard_conversion
- (TYPE_MAIN_VARIANT (non_reference (to)),
- strip_top_quals (non_reference (from)), expr);
+ conv = standard_conversion (to, from, expr);
if (conv)
- {
- if (TREE_CODE (conv) == IDENTITY_CONV && IS_AGGR_TYPE (to)
- && (TREE_CODE (from) == REFERENCE_TYPE || (expr && real_lvalue_p (expr))))
- conv = build_conv (RVALUE_CONV, to, conv);
- }
+ ;
else if ((IS_AGGR_TYPE (non_reference (from))
|| IS_AGGR_TYPE (non_reference (to)))
&& (flags & LOOKUP_NO_CONVERSION) == 0)
break;
case COND_EXPR:
+#if 0
/* Kludge around broken overloading rules whereby
- bool ? const char& : enum is ambiguous. */
+ bool ? const char& : enum is ambiguous
+ (between int and const char&). */
+ /* Not needed for compiles without -pedantic, since the rank compare
+ in joust will pick the int promotion. Let's just leave this out
+ for now. */
flags |= LOOKUP_NO_TEMP_BIND;
+#endif
+
+ /* Extension: Support ?: of enumeral type. Hopefully this will not
+ be an extension for long. */
if (TREE_CODE (type1) == ENUMERAL_TYPE && type1 == type2)
break;
else if (TREE_CODE (type1) == ENUMERAL_TYPE
tree obj, args;
{
struct z_candidate *candidates = 0, *cand;
- tree fns, convs, mem_args, *p;
- enum tree_code code2 = NOP_EXPR;
+ tree fns, convs, mem_args;
tree type = TREE_TYPE (obj);
fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 0);
tree arg1, arg2, arg3;
{
struct z_candidate *candidates = 0, *cand;
- tree fns, mem_arglist, arglist, fnname, *p;
+ tree fns, mem_arglist, arglist, fnname;
enum tree_code code2 = NOP_EXPR;
tree templates = NULL_TREE;
switch (TREE_CODE (convs))
{
- case BASE_CONV:
case RVALUE_CONV:
+ if (! IS_AGGR_TYPE (TREE_TYPE (convs)))
+ return expr;
+ /* else fall through */
+ case BASE_CONV:
return build_user_type_conversion
(TREE_TYPE (convs), expr, LOOKUP_NORMAL);
case REF_BIND:
/* Default arguments */
for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm))
- converted_args = tree_cons
- (NULL_TREE,
- convert_default_arg (TREE_VALUE (parm), TREE_PURPOSE (parm)),
- converted_args);
+ {
+ tree arg = TREE_PURPOSE (parm);
+
+ if (PARM_DEFAULT_FROM_TEMPLATE (parm))
+ /* This came from a template. Instantiate the default arg here,
+ not in tsubst. */
+ arg = tsubst_expr (arg, &TREE_VEC_ELT (DECL_TI_ARGS (fn), 0),
+ TREE_VEC_LENGTH (DECL_TI_ARGS (fn)), NULL_TREE);
+ converted_args = tree_cons
+ (NULL_TREE, convert_default_arg (TREE_VALUE (parm), arg),
+ converted_args);
+ }
/* Ellipsis */
for (; arg; arg = TREE_CHAIN (arg))
break;
if (i == TREE_VEC_LENGTH (cand1->convs))
return 1;
+#if 0
/* Kludge around broken overloading rules whereby
bool ? void *const & : void *const & is ambiguous. */
+ /* Huh? Explain the problem better. */
if (cand1->fn == ansi_opname[COND_EXPR])
{
tree c1 = TREE_VEC_ELT (cand1->convs, 1);
return -1;
}
}
+#endif
}
tweak:
char cant_have_default_ctor;
char cant_have_const_ctor;
char no_const_asn_ref;
- char base_has_virtual;
};
/* Record information about type T derived from its base classes.
if (TYPE_VIRTUAL_P (basetype))
{
- /* Remember that the baseclass has virtual members. */
- b->base_has_virtual = 1;
-
/* Ensure that this is set from at least a virtual base
class. */
if (b->rtti == NULL_TREE)
tree fields = TYPE_FIELDS (t);
tree fn_fields = TYPE_METHODS (t);
tree x, last_x, method_vec;
- int base_has_virtual;
int all_virtual;
int has_virtual;
int max_has_virtual;
cant_have_default_ctor = base_info.cant_have_default_ctor;
cant_have_const_ctor = base_info.cant_have_const_ctor;
no_const_asn_ref = base_info.no_const_asn_ref;
- base_has_virtual = base_info.base_has_virtual;
n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo));
aggregate = 0;
}
cant_have_default_ctor = 0;
cant_have_const_ctor = 0;
no_const_asn_ref = 0;
- base_has_virtual = 0;
}
#if 0
#define DELETE_EXPR_USE_VEC(NODE) TREE_LANG_FLAG_1 (NODE)
#define LOOKUP_EXPR_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
+/* For a TREE_LIST node representing a function parm type and its default arg,
+ did the default arg come from a template? */
+#define PARM_DEFAULT_FROM_TEMPLATE(NODE) TREE_LANG_FLAG_0 (NODE)
+
/* Nonzero in INT_CST means that this int is negative by dint of
using a twos-complement negated operand. */
#define TREE_NEGATED_INT(NODE) (TREE_LANG_FLAG_0 (NODE))
my_friendly_abort (0);
}
+#if 0
+/* Unused -- brendan 970107 */
/* Array for holding types considered "built-in". These types
are output in the module in which `main' is defined. */
static tree *builtin_type_tdescs_arr;
static int builtin_type_tdescs_len, builtin_type_tdescs_max;
+#endif
/* Push the declarations of builtin types into the namespace.
RID_INDEX, if < RID_MAX is the index of the builtin type
init_decl_processing ()
{
tree decl;
- register tree endlink, int_endlink, double_endlink;
+ register tree endlink, int_endlink, double_endlink, unsigned_endlink;
tree fields[20];
/* Data type of memcpy. */
tree memcpy_ftype, strlen_ftype;
tree vb_off_identifier;
/* Function type `char *(char *, char *)' and similar ones */
tree string_ftype_ptr_ptr, int_ftype_string_string;
+ tree sizetype_endlink;
+ tree ptr_ftype, ptr_ftype_unsigned, ptr_ftype_sizetype;
+ tree void_ftype, void_ftype_int, void_ftype_ptr;
/* Have to make these distinct before we try using them. */
lang_name_cplusplus = get_identifier ("C++");
endlink = void_list_node;
int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
double_endlink = tree_cons (NULL_TREE, double_type_node, endlink);
+ unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, endlink);
+
+ ptr_ftype = build_function_type (ptr_type_node, NULL_TREE);
+ ptr_ftype_unsigned = build_function_type (ptr_type_node, unsigned_endlink);
+ sizetype_endlink = tree_cons (NULL_TREE, sizetype, endlink);
+ /* We realloc here because sizetype could be int or unsigned. S'ok. */
+ ptr_ftype_sizetype = build_function_type (ptr_type_node, sizetype_endlink);
+
+ void_ftype = build_function_type (void_type_node, endlink);
+ void_ftype_int = build_function_type (void_type_node, int_endlink);
+ void_ftype_ptr
+ = build_function_type (void_type_node,
+ tree_cons (NULL_TREE, ptr_type_node, endlink));
float_ftype_float
= build_function_type (float_type_node,
= build_function_type (ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, const_ptr_type_node,
- tree_cons (NULL_TREE,
- sizetype,
- endlink))));
+ sizetype_endlink)));
if (flag_huge_objects)
delta_type_node = long_integer_type_node;
BUILT_IN_CONSTANT_P, NULL_PTR);
builtin_return_address_fndecl =
- builtin_function ("__builtin_return_address",
- build_function_type (ptr_type_node,
- tree_cons (NULL_TREE,
- unsigned_type_node,
- endlink)),
+ builtin_function ("__builtin_return_address", ptr_ftype_unsigned,
BUILT_IN_RETURN_ADDRESS, NULL_PTR);
- builtin_function ("__builtin_frame_address",
- build_function_type (ptr_type_node,
- tree_cons (NULL_TREE,
- unsigned_type_node,
- endlink)),
+ builtin_function ("__builtin_frame_address", ptr_ftype_unsigned,
BUILT_IN_FRAME_ADDRESS, NULL_PTR);
- builtin_function ("__builtin_alloca",
- build_function_type (ptr_type_node,
- tree_cons (NULL_TREE,
- sizetype,
- endlink)),
+ builtin_function ("__builtin_alloca", ptr_ftype_sizetype,
BUILT_IN_ALLOCA, "alloca");
builtin_function ("__builtin_ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR);
/* Define alloca, ffs as builtins.
Declare _exit just to mark it as volatile. */
if (! flag_no_builtin && !flag_no_nonansi_builtin)
{
- temp = builtin_function ("alloca",
- build_function_type (ptr_type_node,
- tree_cons (NULL_TREE,
- sizetype,
- endlink)),
+ temp = builtin_function ("alloca", ptr_ftype_sizetype,
BUILT_IN_ALLOCA, NULL_PTR);
/* Suppress error if redefined as a non-function. */
DECL_BUILT_IN_NONANSI (temp) = 1;
temp = builtin_function ("ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR);
/* Suppress error if redefined as a non-function. */
DECL_BUILT_IN_NONANSI (temp) = 1;
- temp = builtin_function ("_exit", build_function_type (void_type_node,
- int_endlink),
+ temp = builtin_function ("_exit", void_ftype_int,
NOT_BUILT_IN, NULL_PTR);
TREE_THIS_VOLATILE (temp) = 1;
TREE_SIDE_EFFECTS (temp) = 1;
NULL_PTR);
builtin_function ("__builtin_labs", long_ftype_long,
BUILT_IN_LABS, NULL_PTR);
- builtin_function ("__builtin_saveregs",
- build_function_type (ptr_type_node, NULL_TREE),
+ builtin_function ("__builtin_saveregs", ptr_ftype,
BUILT_IN_SAVEREGS, NULL_PTR);
builtin_function ("__builtin_classify_type", default_function_type,
BUILT_IN_CLASSIFY_TYPE, NULL_PTR);
- builtin_function ("__builtin_next_arg",
- build_function_type (ptr_type_node, NULL_TREE),
+ builtin_function ("__builtin_next_arg", ptr_ftype,
BUILT_IN_NEXT_ARG, NULL_PTR);
- builtin_function ("__builtin_args_info",
- build_function_type (integer_type_node,
- tree_cons (NULL_TREE,
- integer_type_node,
- endlink)),
+ builtin_function ("__builtin_args_info", int_ftype_int,
BUILT_IN_ARGS_INFO, NULL_PTR);
/* Untyped call and return. */
- builtin_function ("__builtin_apply_args",
- build_function_type (ptr_type_node, NULL_TREE),
+ builtin_function ("__builtin_apply_args", ptr_ftype,
BUILT_IN_APPLY_ARGS, NULL_PTR);
temp = tree_cons (NULL_TREE,
build_pointer_type (build_function_type (void_type_node,
NULL_TREE)),
- tree_cons (NULL_TREE,
- ptr_type_node,
- tree_cons (NULL_TREE,
- sizetype,
- endlink)));
+ ptr_ftype_sizetype);
builtin_function ("__builtin_apply",
build_function_type (ptr_type_node, temp),
BUILT_IN_APPLY, NULL_PTR);
- builtin_function ("__builtin_return",
- build_function_type (void_type_node,
- tree_cons (NULL_TREE,
- ptr_type_node,
- endlink)),
+ builtin_function ("__builtin_return", void_ftype_ptr,
BUILT_IN_RETURN, NULL_PTR);
/* Currently under experimentation. */
/* Declare these functions volatile
to avoid spurious "control drops through" warnings. */
- temp = builtin_function ("abort",
- build_function_type (void_type_node, endlink),
+ temp = builtin_function ("abort", void_ftype,
NOT_BUILT_IN, NULL_PTR);
TREE_THIS_VOLATILE (temp) = 1;
TREE_SIDE_EFFECTS (temp) = 1;
/* Well, these are actually ANSI, but we can't set DECL_BUILT_IN on
them... */
DECL_BUILT_IN_NONANSI (temp) = 1;
- temp = builtin_function ("exit", build_function_type (void_type_node,
- int_endlink),
+ temp = builtin_function ("exit", void_ftype_int,
NOT_BUILT_IN, NULL_PTR);
TREE_THIS_VOLATILE (temp) = 1;
TREE_SIDE_EFFECTS (temp) = 1;
/* Now, C++. */
current_lang_name = lang_name_cplusplus;
- auto_function (ansi_opname[(int) NEW_EXPR],
- build_function_type (ptr_type_node,
- tree_cons (NULL_TREE, sizetype,
- void_list_node)),
+ auto_function (ansi_opname[(int) NEW_EXPR], ptr_ftype_sizetype,
NOT_BUILT_IN);
- auto_function (ansi_opname[(int) VEC_NEW_EXPR],
- build_function_type (ptr_type_node,
- tree_cons (NULL_TREE, sizetype,
- void_list_node)),
+ auto_function (ansi_opname[(int) VEC_NEW_EXPR], ptr_ftype_sizetype,
NOT_BUILT_IN);
- auto_function (ansi_opname[(int) DELETE_EXPR],
- build_function_type (void_type_node,
- tree_cons (NULL_TREE, ptr_type_node,
- void_list_node)),
+ auto_function (ansi_opname[(int) DELETE_EXPR], void_ftype_ptr,
NOT_BUILT_IN);
- auto_function (ansi_opname[(int) VEC_DELETE_EXPR],
- build_function_type (void_type_node,
- tree_cons (NULL_TREE, ptr_type_node,
- void_list_node)),
+ auto_function (ansi_opname[(int) VEC_DELETE_EXPR], void_ftype_ptr,
NOT_BUILT_IN);
abort_fndecl
- = define_function ("__pure_virtual",
- build_function_type (void_type_node, void_list_node),
+ = define_function ("__pure_virtual", void_ftype,
NOT_BUILT_IN, 0, 0);
/* Perform other language dependent initializations. */
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))))
{
/* See also grok_x_components. */
-
- tree fn;
tree *q;
/* Wipe out memory of synthesized methods */
else
maxnode = minnode = integer_zero_node;
- TYPE_VALUES (enumtype) = values;
+ TYPE_VALUES (enumtype) = nreverse (values);
if (processing_template_decl)
return enumtype;
was an actual function definition. */
DECL_INITIAL (fndecl) = error_mark_node;
for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t))
- DECL_RTL (t) = NULL_RTX;
+ DECL_RTL (t) = DECL_INCOMING_RTL (t) = NULL_RTX;
}
if (DECL_STATIC_CONSTRUCTOR (fndecl))
}
case TEMPLATE_CONST_PARM:
- {
- tree r = TREE_VEC_ELT (TREE_VALUE (current_template_parms),
- TEMPLATE_CONST_IDX (t));
- dump_decl (TREE_VALUE (r), -1);
- break;
- }
+ if (current_template_parms)
+ {
+ tree r = TREE_VEC_ELT (TREE_VALUE (current_template_parms),
+ TEMPLATE_CONST_IDX (t));
+ dump_decl (TREE_VALUE (r), -1);
+ }
+ else
+ {
+ OB_PUTS ("<tparm ");
+ OB_PUTI (TEMPLATE_CONST_IDX (t));
+ OB_PUTS (">");
+ }
+ break;
case IDENTIFIER_NODE:
OB_PUTID (t);
tree type = TREE_TYPE (exp);
register enum machine_mode mode = TYPE_MODE (type);
register enum tree_code code = TREE_CODE (exp);
- rtx original_target = target;
int ignore = target == const0_rtx;
if (ignore)
- target = 0, original_target = 0;
+ target = 0;
/* No sense saving up arithmetic to be done
if it's all in the wrong mode to form part of an address.
if (TYPE_NEEDS_DESTRUCTOR (type))
{
- tree expr = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
+ tree expr;
+
+ /* All cleanups must be on the function_obstack. */
+ push_obstacks_nochange ();
+ resume_temporary_allocation ();
+
+ expr = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
expr = build_delete (type, expr, integer_zero_node,
LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
if (expr != error_mark_node)
add_partial_entry (expr);
+
+ pop_obstacks ();
}
}
}
#endif
}
- else
+ else if (basetype != type
+ && ! current_template_parms
+ && ! vec_binfo_member (basetype,
+ TYPE_BINFO_BASETYPES (type))
+ && ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type)))
{
- if (basetype != type
- && ! vec_binfo_member (basetype, TYPE_BINFO_BASETYPES (type))
- && ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type)))
- {
- if (IDENTIFIER_CLASS_VALUE (name))
- goto try_member;
- if (TYPE_USES_VIRTUAL_BASECLASSES (type))
- cp_error ("type `%T' is not an immediate or virtual basetype for `%T'",
- basetype, type);
- else
- cp_error ("type `%T' is not an immediate basetype for `%T'",
- basetype, type);
- return;
- }
+ if (IDENTIFIER_CLASS_VALUE (name))
+ goto try_member;
+ if (TYPE_USES_VIRTUAL_BASECLASSES (type))
+ cp_error ("type `%T' is not an immediate or virtual basetype for `%T'",
+ basetype, type);
+ else
+ cp_error ("type `%T' is not an immediate basetype for `%T'",
+ basetype, type);
+ return;
}
if (purpose_member (basetype, current_base_init_list))
{
tree type, true_type, size, rval;
tree nelts;
- tree alloc_expr, alloc_temp;
+ tree alloc_expr;
int has_array = 0;
enum tree_code code = NEW_EXPR;
- int use_cookie;
+ int use_cookie, nothrow, check_new;
tree pending_sizes = NULL_TREE;
return error_mark_node;
}
+ nothrow = (placement
+ && TREE_TYPE (placement)
+ && IS_AGGR_TYPE (TREE_TYPE (placement))
+ && (TYPE_IDENTIFIER (TREE_TYPE (placement))
+ == get_identifier ("nothrow_t")));
+
+ check_new = flag_check_new || nothrow;
+
#if 1
/* Get a little extra space to store a couple of things before the new'ed
array, if this isn't the default placement new. */
array, if this is either non-placement new or new (nothrow). */
use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)
- && (! placement
- || (IS_AGGR_TYPE (TREE_TYPE (placement))
- && (TYPE_IDENTIFIER (TREE_TYPE (placement))
- == get_identifier ("nothrow_t")))));
+ && (! placement || nothrow));
#endif
if (use_cookie)
TREE_CALLS_NEW (rval) = 1;
}
- if (flag_check_new && rval)
+ if (check_new && rval)
alloc_expr = rval = save_expr (rval);
else
alloc_expr = NULL_TREE;
sorry ("template instantiation with pointer to method that is too complex");
return;
}
- if (TREE_CODE (value) == INTEGER_CST)
+ if (TREE_CODE (value) == INTEGER_CST
+ || TREE_CODE (value) == TEMPLATE_CONST_PARM)
{
build_overload_int (value);
numeric_output_need_bar = 1;
hack_identifier (value, name)
tree value, name;
{
- tree type, context;
+ tree type;
if (TREE_CODE (value) == ERROR_MARK)
{
}
for (; fields; fields = TREE_CHAIN (fields))
{
- tree name, init, t;
+ tree init, t;
tree field = fields;
if (TREE_CODE (field) != FIELD_DECL)
{
int nested = (current_function_decl != NULL_TREE);
tree context = hack_decl_function_context (fndecl);
- tree base = DECL_CLASS_CONTEXT (fndecl);
if (! context)
push_to_top_level ();
{ have_extern_spec = 0; }
;
+extension:
+ EXTENSION
+ { $<itype>$ = pedantic;
+ pedantic = 0; }
+ ;
+
asm_keyword:
ASM_KEYWORD
| GCC_ASM_KEYWORD
{ do_toplevel_using_decl ($1); }
| USING NAMESPACE any_id ';'
{ do_using_directive ($3); }
+ | extension extdef
+ { pedantic = $<itype>1; }
;
using_decl:
primary %prec UNARY
{ $$ = $1; }
/* __extension__ turns off -pedantic for following primary. */
- | EXTENSION
- { $<itype>1 = pedantic;
- pedantic = 0; }
- cast_expr %prec UNARY
- { $$ = $3;
+ | extension cast_expr %prec UNARY
+ { $$ = $2;
pedantic = $<itype>1; }
| '*' cast_expr %prec UNARY
{ $$ = build_x_indirect_ref ($2, "unary *"); }
}
| declmods ';'
{ warning ("empty declaration"); }
+ | extension decl
+ { pedantic = $<itype>1; }
;
/* Any kind of declarator (thus, all declarators allowed
{ $$ = finish_method ($$); }
| ';'
{ $$ = NULL_TREE; }
+ | extension component_decl
+ { $$ = $2;
+ pedantic = $<itype>1; }
;
component_decl_1:
tree template, parmlist;
char *mangled_name;
tree id, t;
- tree code_type_node;
if (TREE_CODE (d1) == IDENTIFIER_NODE)
{
}
}
TYPE_BEING_DEFINED (type) = 1;
- return;
+ return error_mark_node;
}
else if (t)
pattern = TREE_TYPE (t);
tree bases;
int i;
int len = TREE_VEC_LENGTH (pbases);
- BINFO_BASETYPES (binfo) = bases = make_tree_vec (len);
+ bases = make_tree_vec (len);
for (i = 0; i < len; ++i)
{
tree elt;
cp_error ("base class `%T' of `%T' has incomplete type",
TREE_TYPE (elt), type);
}
+ /* Don't initialize this until the vector is filled out, or
+ lookups will crash. */
+ BINFO_BASETYPES (binfo) = bases;
}
}
{
tree value = TYPE_MAIN_VARIANT (type_decays_to
(tsubst (TREE_VALUE (values), args, nargs, in_decl)));
- tree purpose = tsubst_expr (TREE_PURPOSE (values),
- args, nargs, in_decl);
+ /* Don't instantiate default args unless they are used.
+ Handle it in build_over_call instead. */
+ tree purpose = TREE_PURPOSE (values);
tree x = build_tree_list (purpose, value);
+ if (purpose)
+ PARM_DEFAULT_FROM_TEMPLATE (x) = 1;
+
if (first)
TREE_CHAIN (last) = x;
else
default:
;
}
- my_friendly_abort (87);
+ /* else we get two different bindings, so deduction fails. */
return 1;
}
/* else if (typeof arg != tparms[idx])
if (d_defined)
return d;
- else if (pattern_defined)
+
+ /* This needs to happen before any tsubsting. */
+ if (! push_tinst_level (d))
+ return d;
+
+ push_to_top_level ();
+ lineno = DECL_SOURCE_LINE (d);
+ input_filename = DECL_SOURCE_FILE (d);
+
+ /* We need to set up DECL_INITIAL regardless of pattern_defined if the
+ variable is a static const initialized in the class body. */
+ if (TREE_CODE (d) == VAR_DECL
+ && ! DECL_INITIAL (d) && DECL_INITIAL (pattern))
+ {
+ pushclass (DECL_CONTEXT (d), 2);
+ DECL_INITIAL (d) = tsubst_expr
+ (DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
+ TREE_VEC_LENGTH (args), tmpl);
+ popclass (1);
+ }
+
+ /* import_export_decl has to happen after DECL_INITIAL is set up. */
+ if (pattern_defined)
{
repo_template_used (d);
import_export_decl (d);
}
- /* We need to set up DECL_INITIAL regardless of pattern_defined if the
- variable is a static const initialized in the class body. */
- if (TREE_CODE (d) == VAR_DECL
- && ! DECL_INITIAL (d) && DECL_INITIAL (pattern))
- {
- lineno = DECL_SOURCE_LINE (d);
- input_filename = DECL_SOURCE_FILE (d);
-
- pushclass (DECL_CONTEXT (d), 2);
- DECL_INITIAL (d) = tsubst_expr
- (DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
- TREE_VEC_LENGTH (args), tmpl);
- popclass (1);
-
- lineno = line;
- input_filename = file;
- }
-
if (! pattern_defined
|| (TREE_CODE (d) == FUNCTION_DECL && ! DECL_INLINE (d)
&& (! DECL_INTERFACE_KNOWN (d)
|| (TREE_CODE (d) == FUNCTION_DECL && ! nested && ! at_eof))
{
add_pending_template (d);
- return d;
+ goto out;
}
- if (! push_tinst_level (d))
- return d;
-
- push_to_top_level ();
-
lineno = DECL_SOURCE_LINE (d);
input_filename = DECL_SOURCE_FILE (d);
finish_function (lineno, 0, nested);
}
+out:
lineno = line;
input_filename = file;
{
tree type = TREE_TYPE (exp);
tree aref;
- tree vptr, offset;
+ tree offset;
if (TREE_CODE (type) != POINTER_TYPE)
{
get_typeid (type)
tree type;
{
- tree t;
-
if (type == error_mark_node)
return error_mark_node;
/* Breadth-first and depth-first routines for
searching multiple-inheritance lattice for GNU C++.
- Copyright (C) 1987, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1987, 89, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
name = constructor_name (name);
#endif
+ if (xbasetype == current_class_type && TYPE_BEING_DEFINED (xbasetype)
+ && IDENTIFIER_CLASS_VALUE (name))
+ {
+ tree field = IDENTIFIER_CLASS_VALUE (name);
+ if (TREE_CODE (field) != FUNCTION_DECL
+ && ! (want_type && TREE_CODE (field) != TYPE_DECL))
+ return field;
+ }
+
if (TREE_CODE (xbasetype) == TREE_VEC)
{
type = BINFO_TYPE (xbasetype);
&& (vc=virtual_context (current_fndecl, t, vbase)) != vbase)
{
/* This may in fact need a runtime fixup. */
- tree idx = DECL_VINDEX (current_fndecl);
+ tree idx = build_int_2 (n, 0);
tree vtbl = BINFO_VTABLE (binfo);
tree nvtbl = lookup_name (DECL_NAME (vtbl), 0);
tree aref, ref, naref;
register enum tree_code code1;
register enum tree_code code2;
register tree result_type = NULL_TREE;
- tree orig_op1 = op1, orig_op2 = op2;
/* If second operand is omitted, it is the same as the first one;
make sure it is calculated only once. */
tree delta2 = integer_zero_node;
tree vfield_offset;
tree npfn = NULL_TREE;
- tree u;
/* Handle multiple conversions of pointer to member functions. */
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (pfn)))
{
- tree ndelta, ndelta2, nindex;
+ tree ndelta, ndelta2;
tree e1, e2, e3, n;
/* Is is already the right type? */
tree exp;
tree parms;
{
- tree binfo;
-
/* This is either a call to a constructor,
or a C cast in C++'s `functional' notation. */
tree type;