declare sys_errlist and sys_nerr.
(my_strerror): New function.
+Tue Mar 28 14:16:35 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * search.c (get_binfo): Don't try to be so clever.
+
+ * tree.c (copy_to_permanent): Also suspend_momentary().
+
+ * cvt.c (cp_convert_to_pointer): Hand off to convert_fn_pointer even
+ if the types are the same.
+
+ * decl.c (start_function): Handle extern inlines more like C++ says
+ we should.
+
+ * init.c (build_member_call): Hand constructor calls off to
+ build_functional_cast.
+
+ * typeck2.c (build_functional_cast): Use DECL_NESTED_TYPENAME to get
+ the name of the type.
+
+Tue Mar 28 13:13:56 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * decl.c (grokdeclarator): Check for the decl returned by
+ grokfndecl to be null before using build_decl_attribute_variant.
+
+Mon Mar 27 18:04:41 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * init.c (build_new): Use build_pointer_type instead of
+ TYPE_POINTER_TO.
+
Fri Mar 24 12:11:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+ * typeck.c (build_conditional_expr): Handle pmfs.
+ (convert_for_assignment): Fix pmf support.
+
+ * cvt.c (convert_fn_ptr): Support !flag_vtable_thunks.
+ (cp_convert_to_pointer): Handle pmfs.
+ (cp_convert): Pass pmfs to cp_convert_to_pointer.
+
+ * typeck.c (common_type): Handle inheritance for pmfs.
+
+ * typeck2.c (build_m_component_ref): Do access control.
+
+ * typeck.c (comp_target_types): Check for conversion to void *
+ before checking trickier conversions.
+
* decl.c (duplicate_decls): Propagate DECL_ABSTRACT_VIRTUAL_P.
* pt.c (push_tinst_level): Complain if template instantiation depth
convert_fn_ptr (type, expr)
tree type, expr;
{
- tree binfo = get_binfo (TYPE_METHOD_BASETYPE (TREE_TYPE (TREE_TYPE (expr))),
- TYPE_METHOD_BASETYPE (TREE_TYPE (type)),
- 1);
- if (binfo == error_mark_node)
+ if (flag_vtable_thunks)
{
- error (" in pointer to member conversion");
- return error_mark_node;
- }
- if (binfo == NULL_TREE)
- {
- /* ARM 4.8 restriction. */
- error ("invalid pointer to member conversion");
- return error_mark_node;
+ tree intype = TREE_TYPE (expr);
+ tree binfo = get_binfo (TYPE_METHOD_BASETYPE (TREE_TYPE (intype)),
+ TYPE_METHOD_BASETYPE (TREE_TYPE (type)), 1);
+ if (binfo == error_mark_node)
+ {
+ error (" in pointer to member conversion");
+ return error_mark_node;
+ }
+ if (binfo == NULL_TREE)
+ {
+ /* ARM 4.8 restriction. */
+ error ("invalid pointer to member conversion");
+ return error_mark_node;
+ }
+
+ if (BINFO_OFFSET_ZEROP (binfo))
+ return build1 (NOP_EXPR, type, expr);
+ return build1 (NOP_EXPR, type, build_thunk (BINFO_OFFSET (binfo), expr));
}
- if (BINFO_OFFSET_ZEROP (binfo))
- return build1 (NOP_EXPR, type, expr);
- return build1 (NOP_EXPR, type, build_thunk (BINFO_OFFSET (binfo), expr));
+ else
+ return build_ptrmemfunc (type, expr, 1);
}
/* if converting pointer to pointer
tree type, expr;
{
register tree intype = TREE_TYPE (expr);
- register enum tree_code form = TREE_CODE (intype);
-
+ register enum tree_code form;
+
+ if (TYPE_PTRMEMFUNC_P (type))
+ type = TYPE_PTRMEMFUNC_FN_TYPE (type);
+ if (TYPE_PTRMEMFUNC_P (intype))
+ intype = TYPE_PTRMEMFUNC_FN_TYPE (intype);
+
+ form = TREE_CODE (intype);
+
if (form == POINTER_TYPE || form == REFERENCE_TYPE)
{
intype = TYPE_MAIN_VARIANT (intype);
}
}
}
- if (TYPE_MAIN_VARIANT (type) != intype
- && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE
+ if (TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE
&& TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE)
+ && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
return convert_fn_ptr (type, expr);
if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
return truthvalue_conversion (e);
return fold (convert_to_integer (type, e));
}
- if (code == POINTER_TYPE || code == REFERENCE_TYPE)
+ if (code == POINTER_TYPE || code == REFERENCE_TYPE
+ || TYPE_PTRMEMFUNC_P (type))
return fold (cp_convert_to_pointer (type, e));
if (code == REAL_TYPE)
{
decl = grokfndecl (ctype, type, declarator,
virtualp, flags, quals,
raises, friendp ? -1 : 0, publicp);
- decl = build_decl_attribute_variant (decl, decl_machine_attr);
if (decl == NULL_TREE)
return NULL_TREE;
+ decl = build_decl_attribute_variant (decl, decl_machine_attr);
if (explicitp == 2)
DECL_NONCONVERTING_P (decl) = 1;
DECL_EXTERNAL (decl1) = current_extern_inline;
DECL_INTERFACE_KNOWN (decl1) = 1;
}
- else if (current_extern_inline)
- {
- /* `extern inline' acts like a declaration except for
- defining how to inline. So set DECL_EXTERNAL in that case. */
- DECL_EXTERNAL (decl1) = 1;
- DECL_INTERFACE_KNOWN (decl1) = 1;
- }
else
{
/* This is a definition, not a reference.
DECL_EXTERNAL (decl1) = 0;
if (DECL_INLINE (decl1) && (DECL_FUNCTION_MEMBER_P (decl1)
- || DECL_TEMPLATE_INSTANTIATION (decl1)))
+ || DECL_TEMPLATE_INSTANTIATION (decl1)
+ || current_extern_inline))
/* We know nothing yet */;
else
{
decl = build_indirect_ref (decl, NULL_PTR);
+ if (method_name == constructor_name (type)
+ || method_name == constructor_name_full (type))
+ return build_functional_cast (type, parmlist);
if (t = lookup_fnfields (basetype_path, method_name, 0))
return build_method_call (decl, method_name, parmlist, basetype_path,
LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);
{
rval = build_opfncall (code, LOOKUP_GLOBAL|LOOKUP_COMPLAIN,
ptr_type_node, size, placement);
- rval = convert (TYPE_POINTER_TO (true_type), rval);
+ rval = convert (build_pointer_type (true_type), rval);
}
else if (! has_array && flag_this_is_variable > 0
&& TYPE_NEEDS_CONSTRUCTING (true_type) && init != void_type_node)
if (TREE_CODE (parent) == TREE_VEC)
parent = BINFO_TYPE (parent);
- /* unions cannot participate in inheritance relationships */
- else if (TREE_CODE (parent) == UNION_TYPE)
- return NULL_TREE;
- else if (TREE_CODE (parent) != RECORD_TYPE)
+ else if (! IS_AGGR_TYPE_CODE (TREE_CODE (parent)))
my_friendly_abort (89);
if (TREE_CODE (binfo) == TREE_VEC)
type = BINFO_TYPE (binfo);
- else if (TREE_CODE (binfo) == RECORD_TYPE)
+ else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo)))
type = binfo;
- else if (TREE_CODE (binfo) == UNION_TYPE)
- return NULL_TREE;
else
my_friendly_abort (90);
{
register struct obstack *ambient_obstack = current_obstack;
register struct obstack *ambient_saveable_obstack = saveable_obstack;
+ int resume;
if (t == NULL_TREE || TREE_PERMANENT (t))
return t;
saveable_obstack = &permanent_obstack;
current_obstack = saveable_obstack;
+ resume = suspend_momentary ();
t = make_deep_copy (t);
+ resume_momentary (resume);
current_obstack = ambient_obstack;
saveable_obstack = ambient_saveable_obstack;
t1 = build_pointer_type (target);
else
t1 = build_reference_type (target);
- return build_type_attribute_variant (t1, attributes);
+ t1 = build_type_attribute_variant (t1, attributes);
+
+ if (TREE_CODE (target) == METHOD_TYPE)
+ t1 = build_ptrmemfunc_type (t1);
+
+ return t1;
}
#if 0
case POINTER_TYPE:
compiler_error ("common_type called with uncommon aggregate types");
case METHOD_TYPE:
- if (comptypes (TYPE_METHOD_BASETYPE (t1), TYPE_METHOD_BASETYPE (t2), 1)
- && TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2)))
+ if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2)))
{
/* Get this value the long way, since TYPE_METHOD_BASETYPE
is just the main variant of this. */
- tree basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t1)));
+ tree basetype;
tree raises, t3;
+ tree b1 = TYPE_OFFSET_BASETYPE (t1);
+ tree b2 = TYPE_OFFSET_BASETYPE (t2);
+
+ if (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2))
+ basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2)));
+ else
+ {
+ if (binfo_or_else (b2, b1) == NULL_TREE)
+ compiler_error ("common_type called with uncommon method types");
+ basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t1)));
+ }
+
raises = TYPE_RAISES_EXCEPTIONS (t1);
/* If this was a member function type, get back to the
return build_type_attribute_variant (t1, attributes);
case OFFSET_TYPE:
- if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2)))
+ if (TREE_TYPE (t1) == TREE_TYPE (t2))
{
tree b1 = TYPE_OFFSET_BASETYPE (t1);
tree b2 = TYPE_OFFSET_BASETYPE (t2);
- tree base;
if (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2))
- return build_type_attribute_variant (t1, attributes);
- else if (binfo_or_else (b2, b1))
return build_type_attribute_variant (t2, attributes);
+ else if (binfo_or_else (b2, b1))
+ return build_type_attribute_variant (t1, attributes);
}
compiler_error ("common_type called with uncommon member types");
if (nptrs > 0)
{
- if (TREE_CODE (ttl) == POINTER_TYPE
- || TREE_CODE (ttl) == ARRAY_TYPE)
- return comp_ptr_ttypes (ttl, ttr);
- else if (TREE_CODE (ttl) == VOID_TYPE
+ if (TREE_CODE (ttl) == VOID_TYPE
&& TREE_CODE (ttr) != FUNCTION_TYPE
&& TREE_CODE (ttr) != METHOD_TYPE
&& TREE_CODE (ttr) != OFFSET_TYPE)
&& TREE_CODE (ttl) != METHOD_TYPE
&& TREE_CODE (ttl) != OFFSET_TYPE)
return -1;
+ else if (TREE_CODE (ttl) == POINTER_TYPE
+ || TREE_CODE (ttl) == ARRAY_TYPE)
+ return comp_ptr_ttypes (ttl, ttr);
}
return comp_target_types (ttl, ttr, nptrs - 1);
{
if (code2 == ENUMERAL_TYPE)
{
- message_2_types (error, "enumeral mismatch in conditional expression: `%s' vs `%s'", type1, type2);
+ cp_error ("enumeral mismatch in conditional expression: `%T' vs `%T'", type1, type2);
return error_mark_node;
}
else if (extra_warnings && ! IS_AGGR_TYPE_CODE (code2))
{
op1 = default_conversion (op1);
type1 = TREE_TYPE (op1);
+ if (TYPE_PTRMEMFUNC_P (type1))
+ type1 = TYPE_PTRMEMFUNC_FN_TYPE (type1);
code1 = TREE_CODE (type1);
}
if (code2 != VOID_TYPE)
{
op2 = default_conversion (op2);
type2 = TREE_TYPE (op2);
+ if (TYPE_PTRMEMFUNC_P (type2))
+ type2 = TYPE_PTRMEMFUNC_FN_TYPE (type2);
code2 = TREE_CODE (type2);
}
an aggregate value, try converting to a scalar type. */
if (code1 == RECORD_TYPE && code2 == RECORD_TYPE)
{
- message_2_types (error, "aggregate mismatch in conditional expression: `%s' vs `%s'", type1, type2);
+ cp_error ("aggregate mismatch in conditional expression: `%T' vs `%T'", type1, type2);
return error_mark_node;
}
if (code1 == RECORD_TYPE && TYPE_HAS_CONVERSION (type1))
return convert (type, rhs);
/* C++ */
- else if (((coder == POINTER_TYPE && TREE_CODE (rhs) == ADDR_EXPR
- && TREE_CODE (rhstype) == POINTER_TYPE
+ else if (((coder == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (rhstype)) == METHOD_TYPE)
|| integer_zerop (rhs)
|| TYPE_PTRMEMFUNC_P (rhstype))
tree type;
tree objtype = TREE_TYPE (datum);
tree rettype;
+ tree binfo;
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
{
cp_error ("which is of non-aggregate type `%T'", objtype);
return error_mark_node;
}
-
- if (! comptypes (TYPE_METHOD_BASETYPE (type), objtype, 0))
+
+ binfo = get_binfo (TYPE_METHOD_BASETYPE (type), objtype, 1);
+ if (binfo == NULL_TREE)
{
cp_error ("member type `%T::' incompatible with object type `%T'",
TYPE_METHOD_BASETYPE (type), objtype);
return error_mark_node;
}
+ else if (binfo == error_mark_node)
+ return error_mark_node;
return build (OFFSET_REF, rettype, datum, component);
}
{
name = TYPE_NAME (type);
if (TREE_CODE (name) == TYPE_DECL)
- name = DECL_NAME (name);
+ name = DECL_NESTED_TYPENAME (name);
}
if (! IS_AGGR_TYPE (type))