Commit 3c215895 by Jason Merrill

cvt.c, [...]: Clean up more old overloading code, old RTTI code, and some formatting quirks.

	* cvt.c, decl.c, decl2.c, init.c, rtti.c, typeck.c, typeck2.c,
	cp-tree.h: Clean up more old overloading code, old RTTI code, and
	some formatting quirks.

From-SVN: r18391
parent de7987a6
......@@ -2084,7 +2084,6 @@ extern tree convert PROTO((tree, tree));
extern tree convert_force PROTO((tree, tree, int));
extern tree build_type_conversion PROTO((enum tree_code, tree, tree, int));
extern tree build_expr_type_conversion PROTO((int, tree, int));
extern int build_default_binary_type_conversion PROTO((enum tree_code, tree *, tree *));
extern tree type_promotes_to PROTO((tree));
extern tree perform_qualification_conversions PROTO((tree, tree));
......
......@@ -5648,122 +5648,6 @@ init_decl_processing ()
void_type_node);
pushdecl (std_node);
#if 0
if (flag_rtti)
{
/* Must build __t_desc type. Currently, type descriptors look like this:
struct __t_desc
{
const char *name;
int size;
int bits;
struct __t_desc *points_to;
int ivars_count, meths_count;
struct __i_desc *ivars[];
struct __m_desc *meths[];
struct __t_desc *parents[];
struct __t_desc *vbases[];
int offsets[];
};
...as per Linton's paper. */
__t_desc_type_node = make_lang_type (RECORD_TYPE);
__i_desc_type_node = make_lang_type (RECORD_TYPE);
__m_desc_type_node = make_lang_type (RECORD_TYPE);
__t_desc_array_type
= build_array_type (build_pointer_type (__t_desc_type_node),
NULL_TREE);
__i_desc_array_type
= build_array_type (build_pointer_type (__i_desc_type_node),
NULL_TREE);
__m_desc_array_type
= build_array_type (build_pointer_type (__m_desc_type_node),
NULL_TREE);
fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("name"),
string_type_node);
fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("size"),
unsigned_type_node);
fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("bits"),
unsigned_type_node);
fields[3] = build_lang_field_decl (FIELD_DECL,
get_identifier ("points_to"),
build_pointer_type (__t_desc_type_node));
fields[4] = build_lang_field_decl (FIELD_DECL,
get_identifier ("ivars_count"),
integer_type_node);
fields[5] = build_lang_field_decl (FIELD_DECL,
get_identifier ("meths_count"),
integer_type_node);
fields[6] = build_lang_field_decl (FIELD_DECL, get_identifier ("ivars"),
build_pointer_type (__i_desc_array_type));
fields[7] = build_lang_field_decl (FIELD_DECL, get_identifier ("meths"),
build_pointer_type (__m_desc_array_type));
fields[8] = build_lang_field_decl (FIELD_DECL, get_identifier ("parents"),
build_pointer_type (__t_desc_array_type));
fields[9] = build_lang_field_decl (FIELD_DECL, get_identifier ("vbases"),
build_pointer_type (__t_desc_array_type));
fields[10] = build_lang_field_decl (FIELD_DECL, get_identifier ("offsets"),
build_pointer_type (integer_type_node));
finish_builtin_type (__t_desc_type_node, "__t_desc", fields, 10, integer_type_node);
/* ivar descriptors look like this:
struct __i_desc
{
const char *name;
int offset;
struct __t_desc *type;
};
*/
fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("name"),
string_type_node);
fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("offset"),
integer_type_node);
fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("type"),
build_pointer_type (__t_desc_type_node));
finish_builtin_type (__i_desc_type_node, "__i_desc", fields, 2,
integer_type_node);
/* method descriptors look like this:
struct __m_desc
{
const char *name;
int vindex;
struct __t_desc *vcontext;
struct __t_desc *return_type;
void (*address)();
short parm_count;
short required_parms;
struct __t_desc *parm_types[];
};
*/
fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("name"),
string_type_node);
fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("vindex"),
integer_type_node);
fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("vcontext"),
build_pointer_type (__t_desc_type_node));
fields[3] = build_lang_field_decl (FIELD_DECL, get_identifier ("return_type"),
build_pointer_type (__t_desc_type_node));
fields[4] = build_lang_field_decl (FIELD_DECL, get_identifier ("address"),
build_pointer_type (default_function_type));
fields[5] = build_lang_field_decl (FIELD_DECL, get_identifier ("parm_count"),
short_integer_type_node);
fields[6] = build_lang_field_decl (FIELD_DECL, get_identifier ("required_parms"),
short_integer_type_node);
fields[7] = build_lang_field_decl (FIELD_DECL, get_identifier ("parm_types"),
build_pointer_type (build_array_type (build_pointer_type (__t_desc_type_node), NULL_TREE)));
finish_builtin_type (__m_desc_type_node, "__m_desc", fields, 7,
integer_type_node);
}
#endif /*flag_rtti*/
/* Now, C++. */
current_lang_name = lang_name_cplusplus;
......@@ -5811,76 +5695,6 @@ init_decl_processing ()
using_eh_for_cleanups ();
}
/* initialize type descriptor type node of various rtti type. */
int
init_type_desc()
{
tree tdecl;
tdecl = lookup_name (get_identifier ("type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__t_desc_type_node = TREE_TYPE (tdecl);
#if 0
__tp_desc_type_node = build_pointer_type (__t_desc_type_node);
#endif
#if 0
tdecl = lookup_name (get_identifier ("__baselist_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__baselist_desc_type_node = TREE_TYPE (tdecl);
#endif
tdecl = lookup_name (get_identifier ("__builtin_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__bltn_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__user_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__user_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__class_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__class_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_field (__class_desc_type_node,
get_identifier ("access_mode"), 0, 0);
if (tdecl == NULL_TREE)
return 0;
__access_mode_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__attr_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__attr_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__pointer_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__ptr_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__func_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__func_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__ptmf_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__ptmf_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__ptmd_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__ptmd_desc_type_node = TREE_TYPE (tdecl);
return 1;
}
/* Make a definition for a builtin function named NAME and whose data type
is TYPE. TYPE should be a function type with argument types.
FUNCTION_CODE tells later passes how to compile calls to this function.
......
......@@ -781,26 +781,6 @@ grok_method_quals (ctype, function, quals)
return ctype;
}
#if 0 /* Not used. */
/* This routine replaces cryptic DECL_NAMEs with readable DECL_NAMEs.
It leaves DECL_ASSEMBLER_NAMEs with the correct value. */
/* This does not yet work with user defined conversion operators
It should. */
static void
substitute_nice_name (decl)
tree decl;
{
if (DECL_NAME (decl) && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE)
{
char *n = decl_as_string (DECL_NAME (decl), 1);
if (n[strlen (n) - 1] == ' ')
n[strlen (n) - 1] = 0;
DECL_NAME (decl) = get_identifier (n);
}
}
#endif
/* Warn when -fexternal-templates is used and #pragma
interface/implementation is not used all the times it should be,
inform the user. */
......@@ -1051,7 +1031,8 @@ grokclassfn (ctype, cname, function, flags, quals)
if (IDENTIFIER_TYPE_VALUE (cname))
dbuf = build_overload_name (IDENTIFIER_TYPE_VALUE (cname), 1, 1);
else if (IDENTIFIER_LOCAL_VALUE (cname))
dbuf = build_overload_name (TREE_TYPE (IDENTIFIER_LOCAL_VALUE (cname)), 1, 1);
dbuf = build_overload_name (TREE_TYPE (IDENTIFIER_LOCAL_VALUE (cname)),
1, 1);
else
/* Using ctype fixes the `X::Y::~Y()' crash. The cname has no type when
it's defined out of the class definition, since poplevel_class wipes
......@@ -1108,14 +1089,6 @@ grokclassfn (ctype, cname, function, flags, quals)
DECL_ASSEMBLER_NAME (function)
= build_decl_overload (fn_name, these_arg_types,
1 + DECL_CONSTRUCTOR_P (function));
#if 0
/* This code is going into the compiler, but currently, it makes
libg++/src/Integer.cc not compile. The problem is that the nice name
winds up going into the symbol table, and conversion operations look
for the manged name. */
substitute_nice_name (function);
#endif
}
DECL_ARGUMENTS (function) = last_function_parms;
......@@ -1199,8 +1172,7 @@ grok_array_decl (array_expr, index_exp)
type = TREE_TYPE (type);
/* If they have an `operator[]', use that. */
if (TYPE_LANG_SPECIFIC (type)
&& TYPE_OVERLOADS_ARRAY_REF (complete_type (type)))
if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp)))
return build_opfncall (ARRAY_REF, LOOKUP_NORMAL,
array_expr, index_exp, NULL_TREE);
......@@ -1596,7 +1568,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
if (DECL_NAME (value) != NULL_TREE
&& IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_'
&& ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr"))
cp_error ("member `%D' conflicts with virtual function table field name", value);
cp_error ("member `%D' conflicts with virtual function table field name",
value);
/* Stash away type declarations. */
if (TREE_CODE (value) == TYPE_DECL)
......@@ -1953,33 +1926,6 @@ grok_function_init (decl, init)
TYPE_HAS_ABSTRACT_ASSIGN_REF (current_class_type) = 1;
}
}
else if (TREE_CODE (init) == OFFSET_REF
&& TREE_OPERAND (init, 0) == NULL_TREE
&& TREE_CODE (TREE_TYPE (init)) == METHOD_TYPE)
{
tree basetype = DECL_CLASS_CONTEXT (init);
tree basefn = TREE_OPERAND (init, 1);
if (TREE_CODE (basefn) != FUNCTION_DECL)
cp_error ("non-method initializer invalid for method `%D'", decl);
else if (! BINFO_OFFSET_ZEROP (TYPE_BINFO (DECL_CLASS_CONTEXT (basefn))))
sorry ("base member function from other than first base class");
else
{
tree binfo = get_binfo (basetype, TYPE_METHOD_BASETYPE (type), 1);
if (binfo == error_mark_node)
;
else if (binfo == 0)
error_not_base_type (TYPE_METHOD_BASETYPE (TREE_TYPE (init)),
TYPE_METHOD_BASETYPE (type));
else
{
/* Mark this function as being defined,
and give it new rtl. */
DECL_INITIAL (decl) = error_mark_node;
DECL_RTL (decl) = DECL_RTL (basefn);
}
}
}
else
cp_error ("invalid initializer for virtual method `%D'", decl);
}
......@@ -2264,82 +2210,6 @@ finish_anon_union (anon_union_decl)
expand_anon_union_decl (anon_union_decl, NULL_TREE, elems);
}
/* Finish and output a table which is generated by the compiler.
NAME is the name to give the table.
TYPE is the type of the table entry.
INIT is all the elements in the table.
PUBLICP is non-zero if this table should be given external access. */
tree
finish_table (name, type, init, publicp)
tree name, type, init;
int publicp;
{
tree itype, atype, decl;
static tree empty_table;
int is_empty = 0;
tree asmspec;
itype = build_index_type (size_int (list_length (init) - 1));
atype = build_cplus_array_type (type, itype);
layout_type (atype);
if (TREE_VALUE (init) == integer_zero_node
&& TREE_CHAIN (init) == NULL_TREE)
{
#if 0
if (empty_table == NULL_TREE)
#endif
{
empty_table = get_temp_name (atype, 1);
init = build (CONSTRUCTOR, atype, NULL_TREE, init);
TREE_CONSTANT (init) = 1;
TREE_STATIC (init) = 1;
DECL_INITIAL (empty_table) = init;
asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (empty_table)),
IDENTIFIER_POINTER (DECL_NAME (empty_table)));
cp_finish_decl (empty_table, NULL_TREE, asmspec, 0, 0);
}
is_empty = 1;
}
if (name == NULL_TREE)
{
if (is_empty)
return empty_table;
decl = get_temp_name (atype, 1);
}
else
{
decl = build_decl (VAR_DECL, name, atype);
decl = pushdecl (decl);
TREE_STATIC (decl) = 1;
}
if (is_empty == 0)
{
TREE_PUBLIC (decl) = publicp;
init = build (CONSTRUCTOR, atype, NULL_TREE, init);
TREE_CONSTANT (init) = 1;
TREE_STATIC (init) = 1;
DECL_INITIAL (decl) = init;
asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (decl)),
IDENTIFIER_POINTER (DECL_NAME (decl)));
}
else
{
/* This will cause DECL to point to EMPTY_TABLE in rtl-land. */
DECL_EXTERNAL (decl) = 1;
TREE_STATIC (decl) = 0;
init = 0;
asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (empty_table)),
IDENTIFIER_POINTER (DECL_NAME (empty_table)));
}
cp_finish_decl (decl, NULL_TREE, asmspec, 0, 0);
return decl;
}
/* Finish processing a builtin type TYPE. It's name is NAME,
its fields are in the array FIELDS. LEN is the number of elements
in FIELDS minus one, or put another way, it is the maximum subscript
......
......@@ -1589,9 +1589,9 @@ build_member_call (type, name, parmlist)
cp_error ("invalid use of member `%D'", t);
return error_mark_node;
}
if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl))
&& TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (decl)))
return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl, parmlist, NULL_TREE);
if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl)))
return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl,
parmlist, NULL_TREE);
return build_function_call (decl, parmlist);
}
else
......
......@@ -1108,285 +1108,3 @@ synthesize_tinfo_fn (fndecl)
c_expand_return (tmp);
finish_function (lineno, 0, 0);
}
#if 0
/* This is the old dossier type descriptor generation code, it's much
more extended than rtti. It's reserved for later use. */
/* Build an initializer for a __t_desc node. So that we can take advantage
of recursion, we accept NULL for TYPE.
DEFINITION is greater than zero iff we must define the type descriptor
(as opposed to merely referencing it). 1 means treat according to
#pragma interface/#pragma implementation rules. 2 means define as
global and public, no matter what. */
tree
build_t_desc (type, definition)
tree type;
int definition;
{
tree tdecl;
tree tname, name_string;
tree elems, fields;
tree parents, vbases, offsets, ivars, methods, target_type;
int method_count = 0, field_count = 0;
if (type == NULL_TREE)
return NULL_TREE;
tname = build_t_desc_overload (type);
if (IDENTIFIER_AS_DESC (tname)
&& (!definition || TREE_ASM_WRITTEN (IDENTIFIER_AS_DESC (tname))))
return IDENTIFIER_AS_DESC (tname);
tdecl = lookup_name (tname, 0);
if (tdecl == NULL_TREE)
{
tdecl = build_decl (VAR_DECL, tname, __t_desc_type_node);
DECL_EXTERNAL (tdecl) = 1;
TREE_PUBLIC (tdecl) = 1;
tdecl = pushdecl_top_level (tdecl);
}
/* If we previously defined it, return the defined result. */
else if (definition && DECL_INITIAL (tdecl))
return IDENTIFIER_AS_DESC (tname);
if (definition)
{
tree taggr = type;
/* Let T* and T& be written only when T is written (if T is an aggr).
We do this for const, but not for volatile, since volatile
is rare and const is not. */
if (!TYPE_VOLATILE (taggr)
&& (TREE_CODE (taggr) == POINTER_TYPE
|| TREE_CODE (taggr) == REFERENCE_TYPE)
&& IS_AGGR_TYPE (TREE_TYPE (taggr)))
taggr = TREE_TYPE (taggr);
/* If we know that we don't need to write out this type's
vtable, then don't write out it's dossier. Somebody
else will take care of that. */
if (IS_AGGR_TYPE (taggr) && CLASSTYPE_VFIELD (taggr))
{
if (CLASSTYPE_VTABLE_NEEDS_WRITING (taggr))
{
TREE_PUBLIC (tdecl) = ! CLASSTYPE_INTERFACE_ONLY (taggr)
&& CLASSTYPE_INTERFACE_KNOWN (taggr);
DECL_EXTERNAL (tdecl) = 0;
}
else
{
if (write_virtuals != 0)
TREE_PUBLIC (tdecl) = 1;
}
}
else
{
DECL_EXTERNAL (tdecl) = 0;
TREE_PUBLIC (tdecl) = (definition > 1);
}
}
SET_IDENTIFIER_AS_DESC (tname, build_unary_op (ADDR_EXPR, tdecl, 0));
if (!definition || DECL_EXTERNAL (tdecl))
{
/* That's it! */
cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
return IDENTIFIER_AS_DESC (tname);
}
/* Show that we are defining the t_desc for this type. */
DECL_INITIAL (tdecl) = error_mark_node;
parents = build_expr_list (NULL_TREE, integer_zero_node);
vbases = build_expr_list (NULL_TREE, integer_zero_node);
offsets = build_expr_list (NULL_TREE, integer_zero_node);
methods = NULL_TREE;
ivars = NULL_TREE;
if (TYPE_LANG_SPECIFIC (type))
{
int i = CLASSTYPE_N_BASECLASSES (type);
tree method_vec = CLASSTYPE_METHOD_VEC (type);
tree *meth, *end;
tree binfos = TYPE_BINFO_BASETYPES (type);
tree vb = CLASSTYPE_VBASECLASSES (type);
while (--i >= 0)
parents = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (TREE_VEC_ELT (binfos, i)), 0), parents);
while (vb)
{
vbases = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (vb), 0), vbases);
offsets = tree_cons (NULL_TREE, BINFO_OFFSET (vb), offsets);
vb = TREE_CHAIN (vb);
}
if (method_vec)
for (meth = TREE_VEC_END (method_vec),
end = &TREE_VEC_ELT (method_vec, 0); meth-- != end; )
if (*meth)
{
methods = tree_cons (NULL_TREE, build_m_desc (*meth), methods);
method_count++;
}
}
if (IS_AGGR_TYPE (type))
{
for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
if (TREE_CODE (fields) == FIELD_DECL
|| TREE_CODE (fields) == VAR_DECL)
{
ivars = tree_cons (NULL_TREE, build_i_desc (fields), ivars);
field_count++;
}
ivars = nreverse (ivars);
}
parents = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node), parents, 0);
vbases = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node), vbases, 0);
offsets = finish_table (NULL_TREE, integer_type_node, offsets, 0);
if (methods == NULL_TREE)
methods = null_pointer_node;
else
methods = build_unary_op (ADDR_EXPR,
finish_table (NULL_TREE, __m_desc_type_node, methods, 0),
0);
if (ivars == NULL_TREE)
ivars = null_pointer_node;
else
ivars = build_unary_op (ADDR_EXPR,
finish_table (NULL_TREE, __i_desc_type_node, ivars, 0),
0);
if (TREE_TYPE (type))
target_type = build_t_desc (TREE_TYPE (type), definition);
else
target_type = integer_zero_node;
name_string = combine_strings (build_string (IDENTIFIER_LENGTH (tname)+1, IDENTIFIER_POINTER (tname)));
elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
tree_cons (NULL_TREE,
TYPE_SIZE(type)? size_in_bytes(type) : integer_zero_node,
/* really should use bitfield initialization here. */
tree_cons (NULL_TREE, integer_zero_node,
tree_cons (NULL_TREE, target_type,
tree_cons (NULL_TREE, build_int_2 (field_count, 2),
tree_cons (NULL_TREE, build_int_2 (method_count, 2),
tree_cons (NULL_TREE, ivars,
tree_cons (NULL_TREE, methods,
tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, parents, 0),
tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, vbases, 0),
build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, offsets, 0))))))))))));
return build_generic_desc (tdecl, elems);
}
/* Build an initializer for a __i_desc node. */
tree
build_i_desc (decl)
tree decl;
{
tree elems, name_string;
tree taggr;
name_string = DECL_NAME (decl);
name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string)));
/* Now decide whether this ivar should cause it's type to get
def'd or ref'd in this file. If the type we are looking at
has a proxy definition, we look at the proxy (i.e., a
`foo *' is equivalent to a `foo'). */
taggr = TREE_TYPE (decl);
if ((TREE_CODE (taggr) == POINTER_TYPE
|| TREE_CODE (taggr) == REFERENCE_TYPE)
&& TYPE_VOLATILE (taggr) == 0)
taggr = TREE_TYPE (taggr);
elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
tree_cons (NULL_TREE, DECL_FIELD_BITPOS (decl),
build_tree_list (NULL_TREE, build_t_desc (TREE_TYPE (decl),
! IS_AGGR_TYPE (taggr)))));
taggr = build (CONSTRUCTOR, __i_desc_type_node, NULL_TREE, elems);
TREE_CONSTANT (taggr) = 1;
TREE_STATIC (taggr) = 1;
TREE_READONLY (taggr) = 1;
return taggr;
}
/* Build an initializer for a __m_desc node. */
tree
build_m_desc (decl)
tree decl;
{
tree taggr, elems, name_string;
tree parm_count, req_count, vindex, vcontext;
tree parms;
int p_count, r_count;
tree parm_types = NULL_TREE;
for (parms = TYPE_ARG_TYPES (TREE_TYPE (decl)), p_count = 0, r_count = 0;
parms != NULL_TREE; parms = TREE_CHAIN (parms), p_count++)
{
taggr = TREE_VALUE (parms);
if ((TREE_CODE (taggr) == POINTER_TYPE
|| TREE_CODE (taggr) == REFERENCE_TYPE)
&& TYPE_VOLATILE (taggr) == 0)
taggr = TREE_TYPE (taggr);
parm_types = tree_cons (NULL_TREE, build_t_desc (TREE_VALUE (parms),
! IS_AGGR_TYPE (taggr)),
parm_types);
if (TREE_PURPOSE (parms) == NULL_TREE)
r_count++;
}
parm_types = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node),
nreverse (parm_types), 0);
parm_count = build_int_2 (p_count, 0);
req_count = build_int_2 (r_count, 0);
if (DECL_VINDEX (decl))
vindex = DECL_VINDEX (decl);
else
vindex = integer_zero_node;
if (DECL_CONTEXT (decl)
&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
vcontext = build_t_desc (DECL_CONTEXT (decl), 0);
else
vcontext = integer_zero_node;
name_string = DECL_NAME (decl);
if (name_string == NULL)
name_string = DECL_ASSEMBLER_NAME (decl);
name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string)));
/* Now decide whether the return type of this mvar
should cause it's type to get def'd or ref'd in this file.
If the type we are looking at has a proxy definition,
we look at the proxy (i.e., a `foo *' is equivalent to a `foo'). */
taggr = TREE_TYPE (TREE_TYPE (decl));
if ((TREE_CODE (taggr) == POINTER_TYPE
|| TREE_CODE (taggr) == REFERENCE_TYPE)
&& TYPE_VOLATILE (taggr) == 0)
taggr = TREE_TYPE (taggr);
elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
tree_cons (NULL_TREE, vindex,
tree_cons (NULL_TREE, vcontext,
tree_cons (NULL_TREE, build_t_desc (TREE_TYPE (TREE_TYPE (decl)),
! IS_AGGR_TYPE (taggr)),
tree_cons (NULL_TREE, build_c_cast (build_pointer_type (default_function_type), build_unary_op (ADDR_EXPR, decl, 0)),
tree_cons (NULL_TREE, parm_count,
tree_cons (NULL_TREE, req_count,
build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, parm_types, 0)))))))));
taggr = build (CONSTRUCTOR, __m_desc_type_node, NULL_TREE, elems);
TREE_CONSTANT (taggr) = 1;
TREE_STATIC (taggr) = 1;
TREE_READONLY (taggr) = 1;
return taggr;
}
#endif /* dossier */
......@@ -1295,9 +1295,10 @@ build_x_arrow (datum)
type = TREE_TYPE (rval);
}
if (IS_AGGR_TYPE (type) && TYPE_OVERLOADS_ARROW (complete_type (type)))
if (IS_AGGR_TYPE (type))
{
while ((rval = build_opfncall (COMPONENT_REF, LOOKUP_NORMAL, rval, NULL_TREE, NULL_TREE)))
while ((rval = build_opfncall (COMPONENT_REF, LOOKUP_NORMAL, rval,
NULL_TREE, NULL_TREE)))
{
if (rval == error_mark_node)
return error_mark_node;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment