Commit fc378698 by Mike Stump

85th Cygnus<->FSF quick merge

From-SVN: r11587
parent 2a275748
Wed Mar 20 14:51:55 1996 Jason Merrill <jason@yorick.cygnus.com>
* parse.y (named_complex_class_head_sans_basetype): Don't crash on
definition of nonexistent nested type.
* error.c (dump_decl, case TYPE_DECL): Fix decision for whether or
not to say 'typedef'.
Wed Mar 20 00:11:47 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* cp-tree.h (struct lang_type): Make search_slot a tree, not a char*.
* search.c (dfs_walk, dfs_init_vbase_pointers,
expand_upcast_fixups): Remove cast of CLASSTYPE_SEARCH_SLOT.
(dfs_find_vbases): Remove cast for CLASSTYPE_SEARCH_SLOT init.
Tue Mar 19 17:56:03 1996 Jason Merrill <jason@yorick.cygnus.com>
* except.c (build_throw): Support minimal parse.
* pt.c (tsubst_copy): Support THROW_EXPR.
* decl2.c (build_expr_from_tree): Ditto.
* pt.c (mangle_class_name_for_template): Always allocate
scratch_firstobj.
Tue Mar 19 16:34:31 1996 Bob Manson <manson@beauty.cygnus.com>
* cvt.c (cp_convert_to_pointer): Give an appropriate error
when trying to cast from an incomplete type.
Tue Mar 19 16:00:33 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (instantiate_class_template): Don't bother setting up
CLASSTYPE_TAGS explicitly, as the nested types will add
themselves.
Tue Mar 19 15:48:43 1996 Bob Manson <manson@beauty.cygnus.com>
* decl.c (shadow_tag): Remove old error check for usage of
an enum without a previous declaration.
(xref_tag): Add error message about usage of enums without a
previous declaration.
Tue Mar 19 09:21:35 1996 Jason Merrill <jason@yorick.cygnus.com>
* lex.c (do_identifier): Only do name consistency check if we're
parsing.
* pt.c (push_template_decl): Don't crash if we get a member defn
that doesn't match.
* decl.c (xref_tag_from_type): New function to do an xref without
always having to figure out code_type_node.
* cp-tree.h: Declare it.
* pt.c (instantiate_class_template): Use it for friend classes.
(lookup_template_class): Use it.
* typeck2.c (build_functional_cast): Pull out a single parm before
passing it to build_c_cast.
Tue Mar 19 09:07:15 1996 Bob Manson <manson@beauty.cygnus.com>
* expr.c (do_case): Give an error message if a pointer is
given as a case value.
Mon Mar 18 21:57:54 1996 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (build_c_cast): Don't pull single TEMPLATE_DECL out of
an overload list.
* lex.c (cons_up_default_function): Really, now, interface hackery
does not apply to synthesized methods.
Mon Mar 18 18:20:57 1996 Mike Stump <mrs@cygnus.com>
* call.c (build_method_call): Ctors and dtors now have special names
with respect to lookups.
* class.c (add_method): Ditto.
(grow_method): Ditto.
(finish_struct_methods): Ditto.
(warn_hidden): Ditto.
(finish_struct_1): Ditto.
* cvt.c (convert_to_reference): Ditto.
(convert_to_aggr): Ditto.
(cp_convert): Ditto.
* decl2.c (check_classfn): Ditto.
* init.c (expand_member_init): Ditto.
(expand_default_init): Ditto.
(expand_aggr_init_1): Ditto.
(build_offset_ref): Ditto.
(build_new): Ditto.
(build_delete): Ditto.
* lex.c (do_inline_function_hair): Ditto.
* search.c (lookup_field_1): Ditto.
(lookup_fnfields_here): Ditto.
(lookup_field): Ditto.
(lookup_fnfields): Ditto.
(get_virtual_destructor): Ditto.
(dfs_debug_mark): Ditto.
(dfs_pushdecls): Ditto.
(dfs_compress_decls): Ditto.
* tree.c (layout_basetypes): Ditto.
* typeck.c (build_component_ref): Ditto.
(build_x_function_call): Ditto.
(build_modify_expr): Ditto.
(convert_for_initialization): Ditto.
(build_functional_cast): Ditto.
* cp-tree.h (CLASSTYPE_FIRST_CONVERSION): Ditto.
(CTOR_NAME): New.
(DTOR_NAME): New.
* decl.c (ctor_identifier): New.
(dtor_identifier): New.
(init_decl_processing): Set them.
Mon Mar 18 18:00:51 1996 Mike Stump <mrs@cygnus.com>
* typeck.c (build_component_ref): Don't get confused by fields whose
context has no type name, like pointer to member functions.
Mon Mar 18 13:19:03 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (grokdeclarator): Handle typedef without declarator.
* pt.c (tsubst): Handle SCOPE_REF in declarator.
* parse.y (bad_parm): Catch another case of missing `typename'.
* lex.c (yyprint): Handle TYPE_DECLs.
* decl.c (start_function): Don't try to be clever.
* lex.c: Lose compiler_error_with_decl.
* typeck2.c: Lose error_with_aggr_type.
(incomplete_type_error): Use cp_* instead of old functions.
(readonly_error): Ditto.
* typeck.c (convert_arguments): Ditto.
* search.c (lookup_nested_field): Ditto.
* method.c (make_thunk): Ditto.
* decl.c (grokparms): Ditto.
* cp-tree.h: Update.
* tree.c (min_tree_cons): Call copy_to_permanent for the purpose
and value.
Mon Mar 18 11:25:52 1996 Bob Manson <manson@beauty.cygnus.com>
* method.c (build_opfncall): When deleting a pointer to an
array, build a new pointer to the tree past any ARRAY_TYPE
nodes.
Mon Mar 18 10:11:46 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* decl.c (lookup_name_real): Initialize local var TYPE to NULL_TREE.
Fri Mar 15 11:03:57 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (instantiate_decl): Only call import_export_decl if at_eof
and ! DECL_INLINE.
* decl.c (finish_function): Don't set nested based on
hack_decl_function_context.
* parse.y (function_try_block): Check for nested function.
(pending_inlines): Ditto.
* decl2.c (build_expr_from_tree): If a unary op already has a
type, just return it.
* decl2.c (finish_prevtable_vardecl): Use ADJUST_VTABLE_LINKAGE.
* decl2.c (walk_vtables): vardecl_fn returns int; return 1 if it does.
(finish_file): Check the return value of walk_vtables.
(finish_prevtable_vardecl): Return int.
(finish_vtable_vardecl): Ditto.
(prune_vtable_vardecl): Ditto.
* lex.c (set_vardecl_interface_info): Ditto.
* cp-tree.h: Adjust return types.
* class.c (delete_duplicate_fields_1): Don't complain about
duplicate nested types if they're the same type.
(finish_struct): Remove check for duplicate.
* decl2.c (grokfield): Don't check for typedef of anonymous type.
Thu Mar 14 10:00:19 1996 Jason Merrill <jason@yorick.cygnus.com>
* cp-tree.h: Lose SIGNATURE_GROKKING_TYPEDEF.
* decl.c (grokdeclarator): Lose special handling of class-level
typedef. Lose SIGNATURE_GROKKING_TYPEDEF. Set
SIGNATURE_HAS_OPAQUE_TYPEDECLS later.
* cvt.c (convert_pointer_to_real): Retain cv-quals in conversion.
* pt.c (tsubst_copy): Strip cv-quals from destructor name types.
* search.c (compute_access): Fix handling of anonymous union
members.
* class.c (finish_struct_anon): Propagate TREE_{PRIVATE,PROTECTED}
from anonymous unions to their members.
* typeck.c (build_x_function_call): For static member functions,
hand off to build_member_call.
Wed Mar 13 14:03:34 1996 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (build_component_ref): Handle OFFSET_REFs.
* init.c (expand_vec_init): Fix init == 0 case.
Tue Mar 12 14:36:02 1996 Jason Merrill <jason@yorick.cygnus.com>
* init.c (build_new): Pedwarn about init and array new.
(expand_vec_init): Handle lists, use convert_for_initialization
* typeck.c (convert_for_initialization): Pass LOOKUP_NO_CONVERSION
when converting to an aggregate type.
* cvt.c (cp_convert): Pass it through.
* typeck.c (build_conditional_expr): Handle user-defined
conversions to slightly different types.
* decl.c (grokdeclarator): Force an array type in a parm to be
permanent.
* decl2.c (do_using_directive): Sorry.
(do_namespace_alias): Ditto.
* lex.c (real_yylex): Warn about using the `namespace' keyword.
Sun Mar 10 22:26:09 1996 Jason Merrill <jason@yorick.cygnus.com>
* parse.y (datadef): Move call to note_list_got_semicolon up.
Fri Mar 8 11:47:26 1996 Mike Stump <mrs@cygnus.com>
* tree.c (unsave_expr): Don't unsave, UNSAVE_EXPRs.
......
......@@ -1745,11 +1745,15 @@ build_method_call (instance, name, parms, basetype_path, flags)
;
/* call to a constructor... */
else if (basetype_path)
basetype = BINFO_TYPE (basetype_path);
{
basetype = BINFO_TYPE (basetype_path);
if (name == DECL_NAME (TYPE_NAME (basetype)))
name = ctor_identifier;
}
else if (IDENTIFIER_HAS_TYPE_VALUE (name))
{
basetype = IDENTIFIER_TYPE_VALUE (name);
name = constructor_name (basetype);
name = ctor_identifier;
}
else
{
......@@ -1758,7 +1762,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
{
/* Canonicalize the typedef name. */
basetype = TREE_TYPE (typedef_name);
name = TYPE_IDENTIFIER (basetype);
name = ctor_identifier;
}
else
{
......@@ -2046,14 +2050,17 @@ build_method_call (instance, name, parms, basetype_path, flags)
/* Look up function name in the structure type definition. */
/* FIXME Axe most of this now? */
if ((IDENTIFIER_HAS_TYPE_VALUE (name)
&& ! IDENTIFIER_OPNAME_P (name)
&& IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name)))
|| name == constructor_name (basetype))
|| name == constructor_name (basetype)
|| name == ctor_identifier)
{
tree tmp = NULL_TREE;
if (IDENTIFIER_TYPE_VALUE (name) == basetype
|| name == constructor_name (basetype))
|| name == constructor_name (basetype)
|| name == ctor_identifier)
tmp = TYPE_BINFO (basetype);
else
tmp = get_binfo (IDENTIFIER_TYPE_VALUE (name), basetype, 0);
......@@ -2092,19 +2099,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (result == error_mark_node)
return error_mark_node;
#if 0
/* Now, go look for this method name. We do not find destructors here.
Putting `void_list_node' on the end of the parmtypes
fakes out `build_decl_overload' into doing the right thing. */
TREE_CHAIN (last) = void_list_node;
method_name = build_decl_overload (name, parmtypes,
1 + (name == constructor_name (save_basetype)
|| name == constructor_name_full (save_basetype)));
TREE_CHAIN (last) = NULL_TREE;
#endif
for (pass = 0; pass < 2; pass++)
{
struct candidate *candidates;
......@@ -2112,10 +2106,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
int len;
unsigned best = 1;
/* This increments every time we go up the type hierarchy.
The idea is to prefer a function of the derived class if possible. */
int b_or_d = 0;
baselink = result;
if (pass > 0)
......@@ -2167,7 +2157,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
}
while (baselink)
if (baselink)
{
/* We have a hit (of sorts). If the parameter list is
"error_mark_node", or some variant thereof, it won't
......@@ -2183,30 +2173,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
basetype_path = TREE_VALUE (basetype_path);
basetype = BINFO_TYPE (basetype_path);
#if 0
/* Cast the instance variable if necessary. */
if (basetype != TYPE_MAIN_VARIANT
(TREE_TYPE (TREE_TYPE (TREE_VALUE (parms)))))
{
if (basetype == save_basetype)
TREE_VALUE (parms) = instance_ptr;
else
{
tree type = build_pointer_type
(build_type_variant (basetype, constp, volatilep));
TREE_VALUE (parms) = convert_force (type, instance_ptr, 0);
}
}
/* FIXME: this is the wrong place to get an error. Hopefully
the access-control rewrite will make this change more cleanly. */
if (TREE_VALUE (parms) == error_mark_node)
return error_mark_node;
#endif
if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)))
function = DECL_CHAIN (function);
for (; function; function = DECL_CHAIN (function))
{
#ifdef GATHER_STATISTICS
......@@ -2263,14 +2229,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
}
}
/* Now we have run through one link's member functions.
arrange to head-insert this link's links. */
baselink = next_baselink (baselink);
b_or_d += 1;
/* Don't grab functions from base classes. lookup_fnfield will
do the work to get us down into the right place. */
baselink = NULL_TREE;
}
if (pass == 0)
{
tree igv = lookup_name_nonclass (name);
......
......@@ -427,9 +427,9 @@ struct lang_type
unsigned marked4 : 1;
unsigned marked5 : 1;
unsigned marked6 : 1;
unsigned debug_requested : 1;
unsigned use_template : 2;
unsigned debug_requested : 1;
unsigned has_method_call_overloaded : 1;
unsigned private_attr : 1;
unsigned got_semicolon : 1;
......@@ -439,14 +439,13 @@ struct lang_type
unsigned is_signature_reference : 1;
unsigned has_default_implementation : 1;
unsigned grokking_typedef : 1;
unsigned has_opaque_typedecls : 1;
unsigned sigtable_has_been_generated : 1;
unsigned was_anonymous : 1;
unsigned has_real_assignment : 1;
unsigned has_real_assign_ref : 1;
unsigned has_const_init_ref : 1;
unsigned has_complex_init_ref : 1;
unsigned has_complex_assign_ref : 1;
unsigned has_abstract_assign_ref : 1;
......@@ -455,7 +454,7 @@ struct lang_type
/* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */
unsigned dummy : 19;
unsigned dummy : 20;
unsigned n_vancestors : 16;
} type_flags;
......@@ -475,7 +474,7 @@ struct lang_type
union tree_node *tags;
char *memoized_table_entry;
char *search_slot;
union tree_node *search_slot;
#ifdef ONLY_INT_FIELDS
unsigned int mode : 8;
......@@ -604,9 +603,6 @@ struct lang_type
/* Nonzero means that this signature type has a default implementation. */
# define HAS_DEFAULT_IMPLEMENTATION(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_default_implementation)
/* Nonzero means that grokdeclarator works on a signature-local typedef. */
#define SIGNATURE_GROKKING_TYPEDEF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.grokking_typedef)
/* Nonzero means that this signature contains opaque type declarations. */
#define SIGNATURE_HAS_OPAQUE_TYPEDECLS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_opaque_typedecls)
......@@ -664,8 +660,8 @@ struct lang_type
searched with TREE_CHAIN), or the first non-constructor function if
there are no type conversion operators. */
#define CLASSTYPE_FIRST_CONVERSION(NODE) \
TREE_VEC_LENGTH (CLASSTYPE_METHOD_VEC (NODE)) > 1 \
? TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), 1) \
TREE_VEC_LENGTH (CLASSTYPE_METHOD_VEC (NODE)) > 2 \
? TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), 2) \
: NULL_TREE;
/* Pointer from any member function to the head of the list of
......@@ -1491,6 +1487,7 @@ extern tree __ptmf_desc_type_node, __ptmd_desc_type_node;
extern tree type_info_type_node;
extern tree class_star_type_node;
extern tree this_identifier;
extern tree ctor_identifier, dtor_identifier;
extern tree pfn_identifier;
extern tree index_identifier;
extern tree delta_identifier;
......@@ -1675,6 +1672,8 @@ extern int current_function_parms_stored;
#define THIS_NAME "this"
#define DESTRUCTOR_NAME_FORMAT "~%s"
#define FILE_FUNCTION_PREFIX_LEN 9
#define CTOR_NAME "__ct"
#define DTOR_NAME "__dt"
#define IN_CHARGE_NAME "__in_chrg"
......@@ -2047,6 +2046,7 @@ extern tree build_ptrmemfunc_type PROTO((tree));
/* the grokdeclarator prototype is in decl.h */
extern int parmlist_is_exprlist PROTO((tree));
extern tree xref_tag PROTO((tree, tree, tree, int));
extern tree xref_tag_from_type PROTO((tree, tree, int));
extern void xref_basetypes PROTO((tree, tree, tree, tree));
extern tree start_enum PROTO((tree));
extern tree finish_enum PROTO((tree, tree));
......@@ -2099,7 +2099,7 @@ extern void finish_builtin_type PROTO((tree, char *, tree *, int, tree));
extern tree coerce_new_type PROTO((tree));
extern tree coerce_delete_type PROTO((tree));
extern void import_export_vtable PROTO((tree, tree, int));
extern void walk_vtables PROTO((void (*)(), void (*)()));
extern int walk_vtables PROTO((void (*)(), int (*)()));
extern void walk_sigtables PROTO((void (*)(), void (*)()));
extern void finish_file PROTO((void));
extern void warn_if_unknown_interface PROTO((tree));
......@@ -2203,7 +2203,7 @@ extern void reinit_parse_for_function PROTO((void));
extern int *init_parse PROTO((void));
extern void print_parse_statistics PROTO((void));
extern void extract_interface_info PROTO((void));
extern void set_vardecl_interface_info PROTO((tree, tree));
extern int set_vardecl_interface_info PROTO((tree, tree));
extern void do_pending_inlines PROTO((void));
extern void process_next_inline PROTO((tree));
/* skip restore_pending_input */
......@@ -2231,7 +2231,6 @@ extern tree make_lang_type PROTO((enum tree_code));
extern void copy_decl_lang_specific PROTO((tree));
extern void dump_time_statistics PROTO((void));
/* extern void compiler_error PROTO((char *, HOST_WIDE_INT, HOST_WIDE_INT)); */
extern void compiler_error_with_decl PROTO((tree, char *));
extern void yyerror PROTO((char *));
/* in errfn.c */
......@@ -2472,7 +2471,6 @@ extern tree build_ptrmemfunc PROTO((tree, tree, int));
/* in typeck2.c */
extern tree error_not_base_type PROTO((tree, tree));
extern tree binfo_or_else PROTO((tree, tree));
extern void error_with_aggr_type (); /* PROTO((tree, char *, HOST_WIDE_INT)); */
extern void readonly_error PROTO((tree, char *, int));
extern void abstract_virtuals_error PROTO((tree, tree));
extern void signature_error PROTO((tree, tree));
......
......@@ -201,6 +201,14 @@ cp_convert_to_pointer (type, expr)
if (IS_AGGR_TYPE (intype))
{
tree rval;
if (TYPE_SIZE (complete_type (intype)) == NULL_TREE)
{
cp_error ("can't convert from incomplete type `%T' to `%T'",
intype, type);
return error_mark_node;
}
rval = build_type_conversion (CONVERT_EXPR, type, expr, 1);
if (rval)
{
......@@ -774,7 +782,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
if (TYPE_HAS_CONSTRUCTOR (type)
&& ! CLASSTYPE_ABSTRACT_VIRTUALS (type)
&& (rval = build_method_call
(NULL_TREE, constructor_name_full (type),
(NULL_TREE, ctor_identifier,
build_tree_list (NULL_TREE, expr), TYPE_BINFO (type),
LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY
| LOOKUP_ONLYCONVERTING)))
......@@ -785,7 +793,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
{
extern tree static_aggregates;
tree t = get_temp_name (type, toplevel_bindings_p ());
init = build_method_call (t, constructor_name_full (type),
init = build_method_call (t, ctor_identifier,
build_tree_list (NULL_TREE, expr),
TYPE_BINFO (type),
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
......@@ -800,7 +808,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
}
else
{
init = build_method_call (NULL_TREE, constructor_name_full (type),
init = build_method_call (NULL_TREE, ctor_identifier,
build_tree_list (NULL_TREE, expr),
TYPE_BINFO (type),
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
......@@ -919,47 +927,9 @@ convert_to_aggr (type, expr, msgp, protect)
parmlist = tree_cons (NULL_TREE, integer_zero_node, parmlist);
parmtypes = tree_cons (NULL_TREE, build_pointer_type (basetype), parmtypes);
#if 0
method_name = build_decl_overload (name, parmtypes, 1);
/* constructors are up front. */
fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);
if (TYPE_HAS_DESTRUCTOR (basetype))
fndecl = DECL_CHAIN (fndecl);
while (fndecl)
{
if (DECL_ASSEMBLER_NAME (fndecl) == method_name)
{
function = fndecl;
if (protect)
{
if (TREE_PRIVATE (fndecl))
{
can_be_private =
(basetype == current_class_type
|| is_friend (basetype, current_function_decl)
|| purpose_member (basetype, DECL_ACCESS (fndecl)));
if (! can_be_private)
goto found;
}
else if (TREE_PROTECTED (fndecl))
{
if (! can_be_protected)
goto found;
}
}
goto found_and_ok;
}
fndecl = DECL_CHAIN (fndecl);
}
#endif
/* No exact conversion was found. See if an approximate
one will do. */
fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);
if (TYPE_HAS_DESTRUCTOR (basetype))
fndecl = DECL_CHAIN (fndecl);
{
int saw_private = 0;
......@@ -1119,7 +1089,9 @@ convert_pointer_to_real (binfo, expr)
binfo = NULL_TREE;
}
ptr_type = build_pointer_type (type);
ptr_type = cp_build_type_variant (type, TYPE_READONLY (TREE_TYPE (intype)),
TYPE_VOLATILE (TREE_TYPE (intype)));
ptr_type = build_pointer_type (ptr_type);
if (ptr_type == TYPE_MAIN_VARIANT (intype))
return expr;
......@@ -1338,11 +1310,12 @@ cp_convert (type, expr, convtype, flags)
}
if (TYPE_HAS_CONSTRUCTOR (complete_type (type)))
ctor = build_method_call (NULL_TREE, constructor_name_full (type),
ctor = build_method_call (NULL_TREE, ctor_identifier,
build_tree_list (NULL_TREE, e),
TYPE_BINFO (type),
(flags & LOOKUP_NORMAL) | LOOKUP_SPECULATIVELY
| (convtype&CONV_NONCONVERTING ? 0 : LOOKUP_ONLYCONVERTING)
| (convtype & CONV_NONCONVERTING ? 0 : LOOKUP_ONLYCONVERTING)
| (flags & LOOKUP_NO_CONVERSION)
| (conversion ? LOOKUP_NO_CONVERSION : 0));
if (ctor == error_mark_node)
......
......@@ -757,27 +757,27 @@ grok_x_components (specs, components)
/* This code may be needed for UNION_TYPEs as
well. */
tcode = record_type_node;
if (CLASSTYPE_DECLARED_CLASS(t))
if (CLASSTYPE_DECLARED_CLASS (t))
tcode = class_type_node;
else if (IS_SIGNATURE(t))
else if (IS_SIGNATURE (t))
tcode = signature_type_node;
t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0);
if (TYPE_CONTEXT(t))
CLASSTYPE_NO_GLOBALIZE(t) = 1;
if (TYPE_CONTEXT (t))
CLASSTYPE_NO_GLOBALIZE (t) = 1;
return NULL_TREE;
break;
case UNION_TYPE:
case ENUMERAL_TYPE:
if (TREE_CODE(t) == UNION_TYPE)
if (TREE_CODE (t) == UNION_TYPE)
tcode = union_type_node;
else
tcode = enum_type_node;
t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0);
if (TREE_CODE(t) == UNION_TYPE && TYPE_CONTEXT(t))
CLASSTYPE_NO_GLOBALIZE(t) = 1;
if (TREE_CODE (t) == UNION_TYPE && TYPE_CONTEXT (t))
CLASSTYPE_NO_GLOBALIZE (t) = 1;
if (TREE_CODE (t) == UNION_TYPE
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
{
......@@ -1233,7 +1233,11 @@ check_classfn (ctype, function)
end = TREE_VEC_END (method_vec);
/* First suss out ctors and dtors. */
if (*methods && fn_name == DECL_NAME (*methods))
if (*methods && fn_name == DECL_NAME (*methods)
&& DECL_CONSTRUCTOR_P (function))
goto got_it;
if (*++methods && fn_name == DECL_NAME (*methods)
&& DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)))
goto got_it;
while (++methods != end)
......@@ -1295,8 +1299,8 @@ check_classfn (ctype, function)
function, ctype);
}
/* If we did not find the method in the class, add it to
avoid spurious errors. */
/* If we did not find the method in the class, add it to avoid
spurious errors. */
add_method (ctype, methods, function);
return NULL_TREE;
}
......@@ -1381,16 +1385,6 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
DECL_CLASS_CONTEXT (value) = current_class_type;
CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1;
/* If we declare a typedef name for something that has no name,
the typedef name is used for linkage. See 7.1.3 p4 94/0158. */
if (TYPE_NAME (TREE_TYPE (value))
&& TREE_CODE (TYPE_NAME (TREE_TYPE (value))) == TYPE_DECL
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (TREE_TYPE (value))))
{
TYPE_NAME (TREE_TYPE (value)) = value;
TYPE_STUB_DECL (TREE_TYPE (value)) = value;
}
pushdecl_class_level (value);
return value;
}
......@@ -2094,6 +2088,7 @@ get_temp_name (type, staticp)
}
TREE_USED (decl) = 1;
TREE_STATIC (decl) = staticp;
DECL_ARTIFICIAL (decl) = 1;
/* If this is a local variable, then lay out its rtl now.
Otherwise, callers of this function are responsible for dealing
......@@ -2529,7 +2524,7 @@ import_export_template (type)
}
}
static void
static int
finish_prevtable_vardecl (prev, vars)
tree prev, vars;
{
......@@ -2550,6 +2545,9 @@ finish_prevtable_vardecl (prev, vars)
SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method);
CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method);
#ifdef ADJUST_VTABLE_LINKAGE
ADJUST_VTABLE_LINKAGE (vars, method);
#endif
break;
}
}
......@@ -2570,14 +2568,17 @@ finish_prevtable_vardecl (prev, vars)
at the top level. */
build_t_desc (ctype, 1);
}
return 1;
}
static void
static int
finish_vtable_vardecl (prev, vars)
tree prev, vars;
{
if (write_virtuals >= 0
&& ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars)))
&& ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))
&& ! TREE_ASM_WRITTEN (vars))
{
#if 0
/* The long term plan it to make the TD entries statically initialized,
......@@ -2622,29 +2623,33 @@ finish_vtable_vardecl (prev, vars)
#endif /* DWARF_DEBUGGING_INFO */
rest_of_decl_compilation (vars, NULL_PTR, 1, 1);
return 1;
}
else if (! TREE_USED (vars))
/* We don't know what to do with this one yet. */
return;
return 0;
/* We know that PREV must be non-zero here. */
TREE_CHAIN (prev) = TREE_CHAIN (vars);
return 0;
}
static void
static int
prune_vtable_vardecl (prev, vars)
tree prev, vars;
{
/* We know that PREV must be non-zero here. */
TREE_CHAIN (prev) = TREE_CHAIN (vars);
return 1;
}
void
int
walk_vtables (typedecl_fn, vardecl_fn)
register void (*typedecl_fn)();
register void (*vardecl_fn)();
register int (*vardecl_fn)();
{
tree prev, vars;
int flag = 0;
for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars))
{
......@@ -2652,7 +2657,8 @@ walk_vtables (typedecl_fn, vardecl_fn)
if (TREE_CODE (vars) == VAR_DECL && DECL_VIRTUAL_P (vars))
{
if (vardecl_fn) (*vardecl_fn) (prev, vars);
if (vardecl_fn)
flag |= (*vardecl_fn) (prev, vars);
if (prev && TREE_CHAIN (prev) != vars)
continue;
......@@ -2667,6 +2673,8 @@ walk_vtables (typedecl_fn, vardecl_fn)
prev = vars;
}
return flag;
}
static void
......@@ -2910,7 +2918,7 @@ finish_file ()
expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
NULL_TREE));
expand_end_bindings (getdecls(), 1, 0);
expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
......@@ -3027,7 +3035,7 @@ finish_file ()
expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
NULL_TREE));
expand_end_bindings (getdecls(), 1, 0);
expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
......@@ -3107,7 +3115,7 @@ finish_file ()
SET_DECL_ARTIFICIAL (vars);
pushdecl (vars);
walk_vtables ((void (*)())0, finish_vtable_vardecl);
reconsider |= walk_vtables ((void (*)())0, finish_vtable_vardecl);
while (*p)
{
......@@ -3314,6 +3322,8 @@ build_expr_from_tree (t)
case TRUTH_NOT_EXPR:
case ADDR_EXPR:
case CONVERT_EXPR: /* Unary + */
if (TREE_TYPE (t))
return t;
return build_x_unary_op (TREE_CODE (t),
build_expr_from_tree (TREE_OPERAND (t, 0)));
......@@ -3472,6 +3482,9 @@ build_expr_from_tree (t)
(build_expr_from_tree (TREE_OPERAND (t, 0)),
TREE_OPERAND (t, 1), NULL_TREE, 1);
case THROW_EXPR:
return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0)));
default:
return t;
}
......@@ -3599,6 +3612,7 @@ void
do_namespace_alias (alias, namespace)
tree alias, namespace;
{
sorry ("namespace alias");
}
tree
......@@ -3651,6 +3665,7 @@ void
do_using_directive (namespace)
tree namespace;
{
sorry ("using directive");
}
void
......
......@@ -543,7 +543,7 @@ ident_fndecl (t)
#endif
#define GLOBAL_IORD_P(NODE) \
!strncmp(IDENTIFIER_POINTER(NODE),GLOBAL_THING,sizeof(GLOBAL_THING)-1)
! strncmp (IDENTIFIER_POINTER(NODE), GLOBAL_THING, sizeof (GLOBAL_THING) - 1)
void
dump_global_iord (t)
......@@ -581,12 +581,9 @@ dump_decl (t, v)
case TYPE_DECL:
{
/* Don't say 'typedef class A' */
tree type = TREE_TYPE (t);
if (((IS_AGGR_TYPE (type) && ! TYPE_PTRMEMFUNC_P (type))
|| TREE_CODE (type) == ENUMERAL_TYPE)
&& type == TYPE_MAIN_VARIANT (type))
if (DECL_ARTIFICIAL (t))
{
dump_type (type, v);
dump_type (TREE_TYPE (t), v);
break;
}
}
......@@ -1087,7 +1084,7 @@ dump_expr (t, nop)
args = TREE_CHAIN (args);
}
dump_expr (fn, 0);
OB_PUTC('(');
OB_PUTC ('(');
dump_expr_list (args);
OB_PUTC (')');
}
......
......@@ -1398,7 +1398,7 @@ expand_builtin_throw ()
/* Fall into epilogue to unwind prologue. */
}
expand_end_bindings (getdecls(), 1, 0);
expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
......@@ -1626,7 +1626,7 @@ start_anon_func ()
void
end_anon_func ()
{
expand_end_bindings (getdecls(), 1, 0);
expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
......@@ -1809,6 +1809,8 @@ build_throw (e)
{
if (e != error_mark_node)
{
if (current_template_parms)
return build_min (THROW_EXPR, void_type_node, e);
e = build1 (THROW_EXPR, void_type_node, e);
TREE_SIDE_EFFECTS (e) = 1;
TREE_USED (e) = 1;
......
......@@ -366,6 +366,9 @@ do_case (start, end)
{
tree value1 = NULL_TREE, value2 = NULL_TREE, label;
if (start && POINTER_TYPE_P (TREE_TYPE (start)))
error ("pointers are not permitted as case values");
if (end && pedantic)
pedwarn ("ANSI C++ forbids range expressions in switch statement");
......
......@@ -1226,22 +1226,22 @@ 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, 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
UNSAVE_EXPRs, and RTL_EXPRs tweaked so that they can be unsaved, and the
UNSAVE_EXPR code should be in the backend, or alternatively, UNSAVE_EXPR
should be ripped out and exactly one finalization allowed to be expanded
by the backend. I talked with kenner about this, and we have to allow
multiple expansions.
rs6000, PowerPC, Alpha, mips, VAX, and m68k 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 UNSAVE_EXPRs, and RTL_EXPRs tweaked so that they can be
unsaved, and the UNSAVE_EXPR code should be in the backend, or
alternatively, UNSAVE_EXPR should be ripped out and exactly one
finalization allowed to be expanded by the backend. I talked with
kenner about this, and we have to allow multiple expansions.
We only do pointer conversions on exception matching a la 15.3 p2 case
3: `A handler with type T, const T, T&, or const T& is a match for a
......
......@@ -837,6 +837,11 @@ yyprint (file, yychar, yylval)
case SCSPEC:
case PRE_PARSED_CLASS_DECL:
t = yylval.ttype;
if (TREE_CODE (t) == TYPE_DECL)
{
fprintf (file, " `%s'", DECL_NAME (t));
break;
}
my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);
if (IDENTIFIER_POINTER (t))
fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
......@@ -1076,7 +1081,7 @@ set_typedecl_interface_info (prev, vars)
= interface_strcmp (FILE_NAME_NONDIRECTORY (DECL_SOURCE_FILE (vars)));
}
void
int
set_vardecl_interface_info (prev, vars)
tree prev, vars;
{
......@@ -1090,7 +1095,9 @@ set_vardecl_interface_info (prev, vars)
CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
TREE_PUBLIC (vars) = 1;
return 1;
}
return 0;
}
/* Called from the top level: if there are any pending inlines to
......@@ -1683,6 +1690,7 @@ cons_up_default_function (type, full_name, kind)
}
#endif
#if 0
if (CLASSTYPE_INTERFACE_KNOWN (type))
{
DECL_INTERFACE_KNOWN (fn) = 1;
......@@ -1690,6 +1698,7 @@ cons_up_default_function (type, full_name, kind)
&& flag_implement_inlines);
}
else
#endif
DECL_NOT_REALLY_EXTERN (fn) = 1;
mark_inline_for_output (fn);
......@@ -1986,7 +1995,7 @@ check_newline ()
goto skipline;
}
main_filename = TREE_STRING_POINTER (yylval.ttype);
c = getch();
c = getch ();
put_back (c);
}
......@@ -2063,7 +2072,7 @@ check_newline ()
goto skipline;
}
main_filename = TREE_STRING_POINTER (yylval.ttype);
c = getch();
c = getch ();
put_back (c);
}
......@@ -2683,7 +2692,7 @@ see_typename ()
{
looking_for_typename = 1;
if (yychar < 0)
if ((yychar = yylex()) < 0) yychar = 0;
if ((yychar = yylex ()) < 0) yychar = 0;
looking_for_typename = 0;
if (yychar == IDENTIFIER)
{
......@@ -2742,7 +2751,7 @@ do_identifier (token, parsing)
/* Remember that this name has been used in the class definition, as per
[class.scope0] */
if (id && current_class_type
if (id && current_class_type && parsing
&& TYPE_BEING_DEFINED (current_class_type)
&& ! IDENTIFIER_CLASS_VALUE (token))
pushdecl_class_level (id);
......@@ -3238,6 +3247,14 @@ real_yylex ()
token_buffer[0] = '^';
token_buffer[1] = 0;
}
else if (ptr->token == NAMESPACE)
{
static int warned;
if (! warned)
warning ("namespaces are mostly broken in this version of g++");
warned = 1;
}
value = (int) ptr->token;
}
......@@ -4037,7 +4054,7 @@ real_yylex ()
skipnewline:
c = getch ();
if (c == EOF) {
error("Unterminated string");
error ("Unterminated string");
break;
}
}
......@@ -4383,7 +4400,7 @@ build_lang_decl (code, name, type)
#endif
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_decl] += 1;
tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
#endif
return t;
......@@ -4480,7 +4497,7 @@ make_lang_type (code)
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_type] += 1;
tree_node_sizes[(int)lang_type] += sizeof(struct lang_type);
tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
#endif
return t;
......@@ -4509,7 +4526,7 @@ copy_decl_lang_specific (decl)
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_decl] += 1;
tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
#endif
}
......@@ -4549,32 +4566,6 @@ compiler_error (s, v, v2)
sprintf (buf, s, v, v2);
error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
}
void
compiler_error_with_decl (decl, s)
tree decl;
char *s;
{
char *name;
count_error (0);
report_error_function (0);
if (TREE_CODE (decl) == PARM_DECL)
fprintf (stderr, "%s:%d: ",
DECL_SOURCE_FILE (DECL_CONTEXT (decl)),
DECL_SOURCE_LINE (DECL_CONTEXT (decl)));
else
fprintf (stderr, "%s:%d: ",
DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
name = lang_printable_name (decl);
if (name)
fprintf (stderr, s, name);
else
fprintf (stderr, s, "((anonymous))");
fprintf (stderr, " (compiler error)\n");
}
void
yyerror (string)
......
......@@ -91,10 +91,12 @@ do_inline_function_hair (type, friend_list)
if (method && TREE_CODE (method) == TREE_VEC)
{
if (TREE_VEC_ELT (method, 0))
if (TREE_VEC_ELT (method, 1))
method = TREE_VEC_ELT (method, 1);
else if (TREE_VEC_ELT (method, 0))
method = TREE_VEC_ELT (method, 0);
else
method = TREE_VEC_ELT (method, 1);
method = TREE_VEC_ELT (method, 2);
}
while (method)
......@@ -1277,9 +1279,26 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
build_tree_list (NULL_TREE, xarg1),
flags & LOOKUP_COMPLAIN,
(struct candidate *)0);
arg1 = TREE_TYPE (xarg1);
/* This handles the case where we're trying to delete
X (*a)[10];
a=new X[5][10];
delete[] a; */
if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
{
/* Strip off the pointer and the array. */
arg1 = TREE_TYPE (TREE_TYPE (arg1));
while (TREE_CODE (arg1) == ARRAY_TYPE)
arg1 = (TREE_TYPE (arg1));
arg1 = build_pointer_type (arg1);
}
rval = build_method_call
(build_indirect_ref (build1 (NOP_EXPR, TREE_TYPE (xarg1),
(build_indirect_ref (build1 (NOP_EXPR, arg1,
error_mark_node),
NULL_PTR),
fnname, tree_cons (NULL_TREE, xarg1,
......@@ -1826,7 +1845,7 @@ make_thunk (function, delta)
thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);
if (thunk && TREE_CODE (thunk) != THUNK_DECL)
{
error_with_decl ("implementation-reserved name `%s' used");
cp_error ("implementation-reserved name `%D' used", thunk_id);
IDENTIFIER_GLOBAL_VALUE (thunk_id) = thunk = NULL_TREE;
}
if (thunk == NULL_TREE)
......
......@@ -499,10 +499,10 @@ datadef:
| typed_declspecs declarator ';'
{ tree d, specs, attrs;
split_specs_attrs ($1, &specs, &attrs);
note_list_got_semicolon (specs);
d = start_decl ($<ttype>2, specs, 0, NULL_TREE);
cplus_decl_attributes (d, NULL_TREE, attrs);
cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
note_list_got_semicolon ($<ttype>$);
}
| declmods ';'
{ pedwarn ("empty declaration"); }
......@@ -1990,7 +1990,9 @@ pending_inlines:
| pending_inlines fn.defpen maybe_return_init ctor_initializer_opt
compstmt_or_error
{
finish_function (lineno, (int)$4, 0);
int nested = (hack_decl_function_context
(current_function_decl) != NULL_TREE);
finish_function (lineno, (int)$4, nested);
process_next_inline ($2);
}
| pending_inlines fn.defpen maybe_return_init function_try_block
......@@ -2108,7 +2110,19 @@ named_class_head_sans_basetype_defn:
named_complex_class_head_sans_basetype:
aggr nested_name_specifier identifier
{ current_aggr = $$; $$ = $3; }
{
current_aggr = $1;
if (TREE_CODE ($3) == TYPE_DECL)
$$ = $3;
else
{
cp_error ("`%T' does not have a nested type named `%D'",
$2, $3);
$$ = xref_tag
(current_aggr, make_anon_name (), NULL_TREE, 1);
$$ = TYPE_MAIN_DECL ($$);
}
}
| aggr template_type
{ current_aggr = $$; $$ = $2; }
| aggr nested_name_specifier template_type
......@@ -3519,8 +3533,10 @@ function_try_block:
expand_start_all_catch (); }
handler_seq
{
int nested = (hack_decl_function_context
(current_function_decl) != NULL_TREE);
expand_end_all_catch ();
finish_function (lineno, (int)$3, 0);
finish_function (lineno, (int)$3, nested);
}
;
......@@ -3820,6 +3836,9 @@ bad_parm:
| notype_declarator
{
error ("type specifier omitted for parameter");
if (TREE_CODE ($$) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TYPE_PARM)
cp_error (" perhaps you want `typename %E' to make it a type", $$);
$$ = build_tree_list (integer_type_node, $$);
}
;
......
/* Handle parameterized types (templates) for GNU C++.
Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
Rewritten by Jason Merrill (jason@cygnus.com).
This file is part of GNU CC.
......@@ -233,6 +234,9 @@ push_template_decl (decl)
{
if (TREE_CODE (decl) == TYPE_DECL)
tmpl = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl));
else if (! DECL_TEMPLATE_INFO (decl))
/* A member definition that doesn't match anything in the class. */
return;
else
tmpl = DECL_TI_TEMPLATE (decl);
}
......@@ -475,12 +479,10 @@ mangle_class_name_for_template (name, parms, arglist)
int i, nparms;
if (!scratch_firstobj)
{
gcc_obstack_init (&scratch_obstack);
scratch_firstobj = obstack_alloc (&scratch_obstack, 1);
}
gcc_obstack_init (&scratch_obstack);
else
obstack_free (&scratch_obstack, scratch_firstobj);
scratch_firstobj = obstack_alloc (&scratch_obstack, 1);
#if 0
#define buflen sizeof(buf)
......@@ -629,12 +631,6 @@ lookup_template_class (d1, arglist, in_decl)
return error_mark_node;
}
if (TREE_CODE (TREE_TYPE (template)) == RECORD_TYPE)
code_type_node = (CLASSTYPE_DECLARED_CLASS (TREE_TYPE (template))
? class_type_node : record_type_node);
else
code_type_node = union_type_node;
if (PRIMARY_TEMPLATE_P (template))
{
parmlist = DECL_TEMPLATE_PARMS (template);
......@@ -675,7 +671,7 @@ lookup_template_class (d1, arglist, in_decl)
IDENTIFIER_TEMPLATE (id) = d1;
maybe_push_to_top_level (uses_template_parms (arglist));
t = xref_tag (code_type_node, id, NULL_TREE, 1);
t = xref_tag_from_type (TREE_TYPE (template), id, 1);
pop_from_top_level ();
}
else
......@@ -689,7 +685,7 @@ lookup_template_class (d1, arglist, in_decl)
{
tree save_parms = current_template_parms;
current_template_parms = NULL_TREE;
t = xref_tag (code_type_node, id, NULL_TREE, 0);
t = xref_tag_from_type (TREE_TYPE (template), id, 0);
current_template_parms = save_parms;
}
else
......@@ -978,7 +974,7 @@ tree
instantiate_class_template (type)
tree type;
{
tree template, template_info, args, pattern, t, *field_chain, *tag_chain;
tree template, template_info, args, pattern, t, *field_chain;
if (type == error_mark_node)
return error_mark_node;
......@@ -1060,7 +1056,6 @@ instantiate_class_template (type)
CLASSTYPE_LOCAL_TYPEDECLS (type) = CLASSTYPE_LOCAL_TYPEDECLS (pattern);
field_chain = &TYPE_FIELDS (type);
tag_chain = &CLASSTYPE_TAGS (type);
for (t = CLASSTYPE_TAGS (pattern); t; t = TREE_CHAIN (t))
{
......@@ -1068,15 +1063,13 @@ instantiate_class_template (type)
tree tag = TREE_VALUE (t);
tree newtag;
/* These will add themselves to CLASSTYPE_TAGS for the new type. */
if (TREE_CODE (tag) == ENUMERAL_TYPE)
newtag = start_enum (name);
else
newtag = tsubst (tag, &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args), NULL_TREE);
*tag_chain = build_tree_list (name, newtag);
tag_chain = &TREE_CHAIN (*tag_chain);
if (TREE_CODE (tag) == ENUMERAL_TYPE)
{
tree e, values = NULL_TREE, *last = &values;
......@@ -1124,16 +1117,30 @@ instantiate_class_template (type)
TYPE_METHODS (type) = tsubst_chain (TYPE_METHODS (pattern), args);
DECL_FRIENDLIST (TYPE_MAIN_DECL (type))
= tsubst_chain (DECL_FRIENDLIST (TYPE_MAIN_DECL (pattern)), args);
CLASSTYPE_FRIEND_CLASSES (type)
= tsubst_chain (CLASSTYPE_FRIEND_CLASSES (pattern), args);
= tsubst (DECL_FRIENDLIST (TYPE_MAIN_DECL (pattern)),
&TREE_VEC_ELT (args, 0), TREE_VEC_LENGTH (args), NULL_TREE);
{
tree d = tsubst (DECL_TEMPLATE_INJECT (template), &TREE_VEC_ELT (args, 0),
tree d = CLASSTYPE_FRIEND_CLASSES (type) =
tsubst (CLASSTYPE_FRIEND_CLASSES (pattern), &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args), NULL_TREE);
/* This does injection for friend classes. */
for (; d; d = TREE_CHAIN (d))
TREE_VALUE (d) = xref_tag_from_type (TREE_VALUE (d), NULL_TREE, 1);
d = tsubst (DECL_TEMPLATE_INJECT (template), &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args), NULL_TREE);
for (; d; d = TREE_CHAIN (d))
pushdecl (TREE_VALUE (d));
{
tree t = TREE_VALUE (d);
if (TREE_CODE (t) == TYPE_DECL)
/* Already injected. */;
else
pushdecl (t);
}
}
TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
......@@ -1781,6 +1788,11 @@ tsubst (t, args, nargs, in_decl)
(CALL_EXPR, tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl),
tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl), 0);
case SCOPE_REF:
return build_parse_node
(TREE_CODE (t), tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl),
tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl));
default:
sorry ("use of `%s' in template",
tree_code_name [(int) TREE_CODE (t)]);
......@@ -1866,6 +1878,7 @@ tsubst_copy (t, args, nargs, in_decl)
case CONVERT_EXPR: /* Unary + */
case SIZEOF_EXPR:
case ARROW_EXPR:
case THROW_EXPR:
return build1
(code, NULL_TREE,
tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl));
......@@ -1928,7 +1941,7 @@ tsubst_copy (t, args, nargs, in_decl)
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
name = tsubst_copy (TREE_OPERAND (name, 0), args, nargs, in_decl);
name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
name = build1 (BIT_NOT_EXPR, NULL_TREE, TYPE_MAIN_VARIANT (name));
}
else if (TREE_CODE (name) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR)
......@@ -1936,7 +1949,7 @@ tsubst_copy (t, args, nargs, in_decl)
tree base = tsubst_copy (TREE_OPERAND (name, 0), args, nargs, in_decl);
name = TREE_OPERAND (name, 1);
name = tsubst_copy (TREE_OPERAND (name, 0), args, nargs, in_decl);
name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
name = build1 (BIT_NOT_EXPR, NULL_TREE, TYPE_MAIN_VARIANT (name));
name = build_nt (SCOPE_REF, base, name);
}
else
......@@ -2915,7 +2928,7 @@ instantiate_decl (d)
warn_if_unknown_interface (pattern);
}
if (at_eof)
if (at_eof && ! DECL_INLINE (d))
import_export_decl (d);
}
......
......@@ -71,7 +71,7 @@ static int debug_yychar ();
void
init_spew ()
{
gcc_obstack_init(&token_obstack);
gcc_obstack_init (&token_obstack);
}
#ifdef SPEW_DEBUG
......@@ -81,7 +81,7 @@ init_spew ()
static int
num_tokens ()
{
return (obstack_object_size(&token_obstack)/sizeof(struct token))
return (obstack_object_size (&token_obstack) / sizeof (struct token))
- first_token;
}
......@@ -92,8 +92,8 @@ nth_token (n)
{
/* could just have this do slurp_ implicitly, but this way is easier
* to debug... */
my_friendly_assert (n < num_tokens(), 298);
return ((struct token*)obstack_base(&token_obstack))+n+first_token;
my_friendly_assert (n < num_tokens (), 298);
return ((struct token*)obstack_base (&token_obstack)) + n + first_token;
}
/* Add a token to the token fifo. */
......@@ -101,16 +101,16 @@ static void
add_token (t)
struct token* t;
{
obstack_grow(&token_obstack,t,sizeof (struct token));
obstack_grow (&token_obstack, t, sizeof (struct token));
}
/* Consume the next token out of the fifo. */
static void
consume_token()
consume_token ()
{
if (num_tokens() == 1)
if (num_tokens () == 1)
{
obstack_free(&token_obstack, obstack_base (&token_obstack));
obstack_free (&token_obstack, obstack_base (&token_obstack));
first_token = 0;
}
else
......@@ -121,15 +121,15 @@ consume_token()
/* ...otherwise use macros. */
#define num_tokens() \
((obstack_object_size(&token_obstack)/sizeof(struct token)) - first_token)
((obstack_object_size (&token_obstack) / sizeof (struct token)) - first_token)
#define nth_token(N) \
(((struct token*)obstack_base(&token_obstack))+(N)+first_token)
(((struct token*)obstack_base (&token_obstack))+(N)+first_token)
#define add_token(T) obstack_grow(&token_obstack, (T), sizeof (struct token))
#define add_token(T) obstack_grow (&token_obstack, (T), sizeof (struct token))
#define consume_token() \
(num_tokens() == 1 \
(num_tokens () == 1 \
? (obstack_free (&token_obstack, obstack_base (&token_obstack)), \
(first_token = 0)) \
: first_token++)
......@@ -158,11 +158,11 @@ scan_tokens (n)
goto pad_tokens;
}
while (num_tokens() <= n)
while (num_tokens () <= n)
{
obstack_blank(&token_obstack,sizeof (struct token));
obstack_blank (&token_obstack, sizeof (struct token));
tmp = ((struct token *)obstack_next_free (&token_obstack))-1;
tmp->yychar = real_yylex();
tmp->yychar = real_yylex ();
tmp->end_of_file = end_of_file;
tmp->yylval = yylval;
end_of_file = 0;
......@@ -173,7 +173,7 @@ scan_tokens (n)
pad_tokens:
while (num_tokens () <= n)
{
obstack_blank(&token_obstack,sizeof (struct token));
obstack_blank (&token_obstack, sizeof (struct token));
tmp = ((struct token *)obstack_next_free (&token_obstack))-1;
tmp->yychar = EMPTY;
tmp->end_of_file = 0;
......@@ -216,14 +216,14 @@ tree got_scope;
tree got_object;
int
peekyylex()
peekyylex ()
{
scan_tokens (0);
return nth_token (0)->yychar;
}
int
yylex()
yylex ()
{
struct token tmp_token;
tree trrr;
......@@ -233,14 +233,14 @@ yylex()
if (spew_debug)
{
yylex_ctr ++;
fprintf(stderr, "\t\t## %d ##",yylex_ctr);
fprintf (stderr, "\t\t## %d ##", yylex_ctr);
}
#endif
/* if we've got tokens, send them */
if (num_tokens())
if (num_tokens ())
{
tmp_token= *nth_token(0);
tmp_token= *nth_token (0);
/* TMP_TOKEN.YYLVAL.TTYPE may have been allocated on the wrong obstack.
If we don't find it in CURRENT_OBSTACK's current or immediately
......@@ -258,13 +258,13 @@ yylex()
tmp_token.yychar = real_yylex ();
tmp_token.yylval = yylval;
tmp_token.end_of_file = end_of_file;
add_token(&tmp_token);
add_token (&tmp_token);
}
/* many tokens just need to be returned. At first glance, all we
* have to do is send them back up, but some of them are needed to
* figure out local context. */
switch(tmp_token.yychar)
switch (tmp_token.yychar)
{
case EMPTY:
/* This is a lexical no-op. */
......@@ -341,7 +341,7 @@ yylex()
break;
case AGGR:
*nth_token(0) = tmp_token;
*nth_token (0) = tmp_token;
do_aggr ();
/* fall through to output... */
case ENUM:
......@@ -349,7 +349,7 @@ yylex()
looking_for_typename = 1;
/* fall through... */
default:
consume_token();
consume_token ();
}
got_object = NULL_TREE;
......@@ -358,7 +358,7 @@ yylex()
end_of_file = tmp_token.end_of_file;
#ifdef SPEW_DEBUG
if (spew_debug)
debug_yychar(yychar);
debug_yychar (yychar);
#endif
return yychar;
}
......@@ -423,7 +423,7 @@ debug_yychar (yy)
int i;
if(yy<256) {
if (yy<256) {
fprintf (stderr, "<%d: %c >\n", yy, yy);
return 0;
}
......
......@@ -800,9 +800,9 @@ layout_basetypes (rec, binfos)
vbase_decls = decl;
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE)
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1)) == NULL_TREE)
{
warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0),
warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1),
"destructor `%s' non-virtual");
warning ("in inheritance relationship `%s: virtual %s'",
TYPE_NAME_STRING (rec),
......@@ -827,9 +827,9 @@ layout_basetypes (rec, binfos)
claim it as theirs and explain exactly what circumstances
warrant the warning. */
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE)
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1)) == NULL_TREE)
{
warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0),
warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1),
"destructor `%s' non-virtual");
warning ("in inheritance relationship `%s:%s %s'",
TYPE_NAME_STRING (rec),
......@@ -1950,7 +1950,8 @@ min_tree_cons (purpose, value, chain)
register struct obstack *ambient_obstack = current_obstack;
current_obstack = &permanent_obstack;
node = tree_cons (purpose, value, chain);
node = tree_cons (copy_to_permanent (purpose),
copy_to_permanent (value), chain);
current_obstack = ambient_obstack;
return node;
}
......
......@@ -1767,6 +1767,12 @@ build_component_ref (datum, component, basetype_path, protect)
basetype = TREE_TYPE (datum);
code = TREE_CODE (basetype);
}
if (TREE_CODE (datum) == OFFSET_REF)
{
datum = resolve_offset_ref (datum);
basetype = TREE_TYPE (datum);
code = TREE_CODE (basetype);
}
/* First, see if there is a field or component with name COMPONENT. */
if (TREE_CODE (component) == TREE_LIST)
......@@ -1803,7 +1809,7 @@ build_component_ref (datum, component, basetype_path, protect)
cp_error ("type `%T' has no destructor", basetype);
return error_mark_node;
}
return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);
return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1);
}
/* Look up component name in the structure type definition. */
......@@ -1905,7 +1911,8 @@ build_component_ref (datum, component, basetype_path, protect)
{
tree context = DECL_FIELD_CONTEXT (field);
tree base = context;
while (base != basetype && ANON_AGGRNAME_P (TYPE_IDENTIFIER (base)))
while (base != basetype && TYPE_NAME (base)
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (base)))
{
base = TYPE_CONTEXT (base);
}
......@@ -1935,7 +1942,7 @@ build_component_ref (datum, component, basetype_path, protect)
basetype = base;
/* Handle things from anon unions here... */
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (context)))
if (TYPE_NAME (context) && ANON_AGGRNAME_P (TYPE_IDENTIFIER (context)))
{
tree subfield = lookup_anon_field (basetype, context);
tree subdatum = build_component_ref (datum, subfield,
......@@ -2231,6 +2238,23 @@ build_x_function_call (function, params, decl)
return build_min_nt (CALL_EXPR, function, params, 0);
type = TREE_TYPE (function);
if (TREE_CODE (type) == OFFSET_TYPE
&& TREE_TYPE (type) == unknown_type_node
&& TREE_CODE (function) == TREE_LIST
&& TREE_CHAIN (function) == NULL_TREE)
{
/* Undo (Foo:bar)()... */
type = TYPE_OFFSET_BASETYPE (type);
function = TREE_VALUE (function);
my_friendly_assert (TREE_CODE (function) == TREE_LIST, 999);
my_friendly_assert (TREE_CHAIN (function) == NULL_TREE, 999);
function = TREE_VALUE (function);
my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 999);
function = DECL_NAME (function);
return build_method_call (decl, function, params, TYPE_BINFO (type), LOOKUP_NORMAL);
}
is_method = ((TREE_CODE (function) == TREE_LIST
&& current_class_type != NULL_TREE
&& IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (function)) == function)
......@@ -2238,6 +2262,11 @@ build_x_function_call (function, params, decl)
|| TREE_CODE (type) == METHOD_TYPE
|| TYPE_PTRMEMFUNC_P (type));
if (TREE_CODE (function) == FUNCTION_DECL
&& DECL_STATIC_FUNCTION_P (function))
return build_member_call
(DECL_CONTEXT (function), DECL_NAME (function), params);
/* Handle methods, friends, and overloaded functions, respectively. */
if (is_method)
{
......@@ -2712,9 +2741,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
{
if (fndecl)
{
char *buf = (char *)alloca (40 + strlen (called_thing));
sprintf (buf, "too many arguments to %s `%%s'", called_thing);
error_with_decl (fndecl, buf);
cp_error_at ("too many arguments to %s `%+D'", called_thing,
fndecl);
error ("at this point in file");
}
else
......@@ -4877,30 +4905,42 @@ build_conditional_expr (ifexp, op1, op2)
cp_error ("aggregate mismatch in conditional expression: `%T' vs `%T'", type1, type2);
return error_mark_node;
}
/* Warning: this code assumes that conversion between cv-variants of
a type is done using NOP_EXPRs. */
if (code1 == RECORD_TYPE && TYPE_HAS_CONVERSION (type1))
{
tree tmp = build_type_conversion (CONVERT_EXPR, type2, op1, 0);
tree tmp = build_pointer_type
(build_type_variant (TREE_TYPE (type2), 1, 1));
tmp = build_type_conversion (CONVERT_EXPR, tmp, op1, 0);
if (tmp == NULL_TREE)
{
cp_error ("aggregate type `%T' could not convert on lhs of `:'", type1);
cp_error ("incompatible types `%T' and `%T' in `?:'",
type1, type2);
return error_mark_node;
}
if (tmp == error_mark_node)
error ("ambiguous pointer conversion");
result_type = type2;
else
STRIP_NOPS (tmp);
result_type = common_type (type1, TREE_TYPE (tmp));
op1 = tmp;
}
else if (code2 == RECORD_TYPE && TYPE_HAS_CONVERSION (type2))
{
tree tmp = build_type_conversion (CONVERT_EXPR, type1, op2, 0);
tree tmp = build_pointer_type
(build_type_variant (TREE_TYPE (type1), 1, 1));
tmp = build_type_conversion (CONVERT_EXPR, tmp, op2, 0);
if (tmp == NULL_TREE)
{
cp_error ("aggregate type `%T' could not convert on rhs of `:'", type2);
cp_error ("incompatible types `%T' and `%T' in `?:'",
type1, type2);
return error_mark_node;
}
if (tmp == error_mark_node)
error ("ambiguous pointer conversion");
result_type = type1;
else
STRIP_NOPS (tmp);
result_type = common_type (type1, TREE_TYPE (tmp));
op2 = tmp;
}
else if (flag_cond_mismatch)
......@@ -5183,12 +5223,6 @@ build_c_cast (type, expr, allow_nonconverting)
return error_mark_node;
}
/* If there's only one function in the overloaded space,
just take it. */
if (TREE_CODE (value) == TREE_LIST
&& TREE_CHAIN (value) == NULL_TREE)
value = TREE_VALUE (value);
if (current_template_parms)
{
tree t = build_min (CAST_EXPR, type,
......@@ -5471,9 +5505,9 @@ build_modify_expr (lhs, modifycode, rhs)
/* Do the default thing */;
else
{
result = build_method_call (lhs, constructor_name_full (lhstype),
result = build_method_call (lhs, ctor_identifier,
build_tree_list (NULL_TREE, rhs),
NULL_TREE, LOOKUP_NORMAL);
TYPE_BINFO (lhstype), LOOKUP_NORMAL);
if (result == NULL_TREE)
return error_mark_node;
return result;
......@@ -6688,7 +6722,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
{
if (TYPE_HAS_INIT_REF (type))
{
tree init = build_method_call (exp, constructor_name_full (type),
tree init = build_method_call (exp, ctor_identifier,
build_tree_list (NULL_TREE, rhs),
TYPE_BINFO (type), LOOKUP_NORMAL);
......@@ -6721,7 +6755,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
return rhs;
}
return cp_convert (type, rhs, CONV_OLD_CONVERT, flags);
return cp_convert (type, rhs, CONV_OLD_CONVERT,
flags | LOOKUP_NO_CONVERSION);
}
if (type == TREE_TYPE (rhs))
......
......@@ -71,29 +71,6 @@ binfo_or_else (parent_or_type, type)
return NULL_TREE;
}
/* Print an error message stemming from an invalid use of an
aggregate type.
TYPE is the type or binfo which draws the error.
MSG is the message to print.
ARG is an optional argument which may provide more information. */
void
error_with_aggr_type (type, msg, arg)
tree type;
char *msg;
HOST_WIDE_INT arg;
{
tree name;
if (TREE_CODE (type) == TREE_VEC)
type = BINFO_TYPE (type);
name = TYPE_NAME (type);
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
error (msg, IDENTIFIER_POINTER (name), arg);
}
/* According to ARM $7.1.6, "A `const' object may be initialized, but its
value may not be changed thereafter. Thus, we emit hard errors for these,
rather than just pedwarns. If `SOFT' is 1, then we just pedwarn. (For
......@@ -108,40 +85,37 @@ readonly_error (arg, string, soft)
void (*fn)();
if (soft)
fn = pedwarn;
fn = cp_pedwarn;
else
fn = error;
fn = cp_error;
if (TREE_CODE (arg) == COMPONENT_REF)
{
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
fmt = "%s of member `%s' in read-only structure";
fmt = "%s of member `%D' in read-only structure";
else
fmt = "%s of read-only member `%s'";
(*fn) (fmt, string, lang_printable_name (TREE_OPERAND (arg, 1)));
fmt = "%s of read-only member `%D'";
(*fn) (fmt, string, TREE_OPERAND (arg, 1));
}
else if (TREE_CODE (arg) == VAR_DECL)
{
if (DECL_LANG_SPECIFIC (arg)
&& DECL_IN_AGGR_P (arg)
&& !TREE_STATIC (arg))
fmt = "%s of constant field `%s'";
fmt = "%s of constant field `%D'";
else
fmt = "%s of read-only variable `%s'";
(*fn) (fmt, string, lang_printable_name (arg));
fmt = "%s of read-only variable `%D'";
(*fn) (fmt, string, arg);
}
else if (TREE_CODE (arg) == PARM_DECL)
(*fn) ("%s of read-only parameter `%s'", string,
lang_printable_name (arg));
(*fn) ("%s of read-only parameter `%D'", string, arg);
else if (TREE_CODE (arg) == INDIRECT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))) == REFERENCE_TYPE
&& (TREE_CODE (TREE_OPERAND (arg, 0)) == VAR_DECL
|| TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL))
(*fn) ("%s of read-only reference `%s'",
string, lang_printable_name (TREE_OPERAND (arg, 0)));
(*fn) ("%s of read-only reference `%D'", string, TREE_OPERAND (arg, 0));
else if (TREE_CODE (arg) == RESULT_DECL)
(*fn) ("%s of read-only named return value `%s'",
string, lang_printable_name (arg));
(*fn) ("%s of read-only named return value `%D'", string, arg);
else
(*fn) ("%s of read-only location", string);
}
......@@ -239,8 +213,7 @@ incomplete_type_error (value, type)
if (value != 0 && (TREE_CODE (value) == VAR_DECL
|| TREE_CODE (value) == PARM_DECL))
error ("`%s' has an incomplete type",
IDENTIFIER_POINTER (DECL_NAME (value)));
cp_error ("`%D' has incomplete type", value);
else
{
retry:
......@@ -249,15 +222,9 @@ incomplete_type_error (value, type)
switch (TREE_CODE (type))
{
case RECORD_TYPE:
errmsg = "invalid use of undefined type `struct %s'";
break;
case UNION_TYPE:
errmsg = "invalid use of undefined type `union %s'";
break;
case ENUMERAL_TYPE:
errmsg = "invalid use of undefined type `enum %s'";
errmsg = "invalid use of undefined type `%#T'";
break;
case VOID_TYPE:
......@@ -281,7 +248,7 @@ incomplete_type_error (value, type)
my_friendly_abort (108);
}
error_with_aggr_type (type, errmsg);
cp_error (errmsg, type);
}
}
......@@ -1410,28 +1377,23 @@ build_m_component_ref (datum, component)
return build (OFFSET_REF, rettype, datum, component);
}
/* Return a tree node for the expression TYPENAME '(' PARMS ')'.
Because we cannot tell whether this construct is really a call to a
constructor or a request for a type conversion, we try both, and
report any ambiguities we find. */
/* Return a tree node for the expression TYPENAME '(' PARMS ')'. */
tree
build_functional_cast (exp, parms)
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, name = NULL_TREE;
tree expr_as_ctor = NULL_TREE;
tree type;
if (exp == error_mark_node || parms == error_mark_node)
return error_mark_node;
if (TREE_CODE (exp) == IDENTIFIER_NODE)
{
name = exp;
if (IDENTIFIER_HAS_TYPE_VALUE (exp))
/* Either an enum or an aggregate type. */
type = IDENTIFIER_TYPE_VALUE (exp);
......@@ -1440,7 +1402,7 @@ build_functional_cast (exp, parms)
type = lookup_name (exp, 1);
if (!type || TREE_CODE (type) != TYPE_DECL)
{
cp_error ("`%T' fails to be a typedef or built-in type", name);
cp_error ("`%T' fails to be a typedef or built-in type", exp);
return error_mark_node;
}
type = TREE_TYPE (type);
......@@ -1482,13 +1444,6 @@ build_functional_cast (exp, parms)
then the slot being initialized will be filled in. */
if (name == NULL_TREE)
{
name = TYPE_NAME (type);
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NESTED_TYPENAME (name);
}
if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
{
cp_error ("type `%T' is not yet defined", type);
......@@ -1496,15 +1451,15 @@ build_functional_cast (exp, parms)
}
if (parms && TREE_CHAIN (parms) == NULL_TREE)
return build_c_cast (type, parms, 1);
return build_c_cast (type, TREE_VALUE (parms), 1);
expr_as_ctor = build_method_call (NULL_TREE, name, parms,
NULL_TREE, LOOKUP_NORMAL);
exp = build_method_call (NULL_TREE, ctor_identifier, parms,
TYPE_BINFO (type), LOOKUP_NORMAL);
if (expr_as_ctor == error_mark_node)
if (exp == error_mark_node)
return error_mark_node;
return build_cplus_new (type, expr_as_ctor);
return build_cplus_new (type, exp);
}
/* Return the character string for the name that encodes the
......
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