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> Fri Mar 8 11:47:26 1996 Mike Stump <mrs@cygnus.com>
* tree.c (unsave_expr): Don't unsave, UNSAVE_EXPRs. * tree.c (unsave_expr): Don't unsave, UNSAVE_EXPRs.
......
...@@ -1745,11 +1745,15 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -1745,11 +1745,15 @@ build_method_call (instance, name, parms, basetype_path, flags)
; ;
/* call to a constructor... */ /* call to a constructor... */
else if (basetype_path) 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)) else if (IDENTIFIER_HAS_TYPE_VALUE (name))
{ {
basetype = IDENTIFIER_TYPE_VALUE (name); basetype = IDENTIFIER_TYPE_VALUE (name);
name = constructor_name (basetype); name = ctor_identifier;
} }
else else
{ {
...@@ -1758,7 +1762,7 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -1758,7 +1762,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
{ {
/* Canonicalize the typedef name. */ /* Canonicalize the typedef name. */
basetype = TREE_TYPE (typedef_name); basetype = TREE_TYPE (typedef_name);
name = TYPE_IDENTIFIER (basetype); name = ctor_identifier;
} }
else else
{ {
...@@ -2046,14 +2050,17 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -2046,14 +2050,17 @@ build_method_call (instance, name, parms, basetype_path, flags)
/* Look up function name in the structure type definition. */ /* Look up function name in the structure type definition. */
/* FIXME Axe most of this now? */
if ((IDENTIFIER_HAS_TYPE_VALUE (name) if ((IDENTIFIER_HAS_TYPE_VALUE (name)
&& ! IDENTIFIER_OPNAME_P (name) && ! IDENTIFIER_OPNAME_P (name)
&& IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name))) && IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name)))
|| name == constructor_name (basetype)) || name == constructor_name (basetype)
|| name == ctor_identifier)
{ {
tree tmp = NULL_TREE; tree tmp = NULL_TREE;
if (IDENTIFIER_TYPE_VALUE (name) == basetype if (IDENTIFIER_TYPE_VALUE (name) == basetype
|| name == constructor_name (basetype)) || name == constructor_name (basetype)
|| name == ctor_identifier)
tmp = TYPE_BINFO (basetype); tmp = TYPE_BINFO (basetype);
else else
tmp = get_binfo (IDENTIFIER_TYPE_VALUE (name), basetype, 0); tmp = get_binfo (IDENTIFIER_TYPE_VALUE (name), basetype, 0);
...@@ -2092,19 +2099,6 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -2092,19 +2099,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (result == error_mark_node) if (result == error_mark_node)
return 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++) for (pass = 0; pass < 2; pass++)
{ {
struct candidate *candidates; struct candidate *candidates;
...@@ -2112,10 +2106,6 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -2112,10 +2106,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
int len; int len;
unsigned best = 1; 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; baselink = result;
if (pass > 0) if (pass > 0)
...@@ -2167,7 +2157,7 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -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 /* We have a hit (of sorts). If the parameter list is
"error_mark_node", or some variant thereof, it won't "error_mark_node", or some variant thereof, it won't
...@@ -2183,30 +2173,6 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -2183,30 +2173,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
basetype_path = TREE_VALUE (basetype_path); basetype_path = TREE_VALUE (basetype_path);
basetype = BINFO_TYPE (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)) for (; function; function = DECL_CHAIN (function))
{ {
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
...@@ -2263,14 +2229,8 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -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) if (pass == 0)
{ {
tree igv = lookup_name_nonclass (name); tree igv = lookup_name_nonclass (name);
......
...@@ -427,9 +427,9 @@ struct lang_type ...@@ -427,9 +427,9 @@ struct lang_type
unsigned marked4 : 1; unsigned marked4 : 1;
unsigned marked5 : 1; unsigned marked5 : 1;
unsigned marked6 : 1; unsigned marked6 : 1;
unsigned debug_requested : 1;
unsigned use_template : 2; unsigned use_template : 2;
unsigned debug_requested : 1;
unsigned has_method_call_overloaded : 1; unsigned has_method_call_overloaded : 1;
unsigned private_attr : 1; unsigned private_attr : 1;
unsigned got_semicolon : 1; unsigned got_semicolon : 1;
...@@ -439,14 +439,13 @@ struct lang_type ...@@ -439,14 +439,13 @@ struct lang_type
unsigned is_signature_reference : 1; unsigned is_signature_reference : 1;
unsigned has_default_implementation : 1; unsigned has_default_implementation : 1;
unsigned grokking_typedef : 1;
unsigned has_opaque_typedecls : 1; unsigned has_opaque_typedecls : 1;
unsigned sigtable_has_been_generated : 1; unsigned sigtable_has_been_generated : 1;
unsigned was_anonymous : 1; unsigned was_anonymous : 1;
unsigned has_real_assignment : 1; unsigned has_real_assignment : 1;
unsigned has_real_assign_ref : 1; unsigned has_real_assign_ref : 1;
unsigned has_const_init_ref : 1; unsigned has_const_init_ref : 1;
unsigned has_complex_init_ref : 1; unsigned has_complex_init_ref : 1;
unsigned has_complex_assign_ref : 1; unsigned has_complex_assign_ref : 1;
unsigned has_abstract_assign_ref : 1; unsigned has_abstract_assign_ref : 1;
...@@ -455,7 +454,7 @@ struct lang_type ...@@ -455,7 +454,7 @@ struct lang_type
/* The MIPS compiler gets it wrong if this struct also /* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */ member `dummy' with new bits if you go over the edge. */
unsigned dummy : 19; unsigned dummy : 20;
unsigned n_vancestors : 16; unsigned n_vancestors : 16;
} type_flags; } type_flags;
...@@ -475,7 +474,7 @@ struct lang_type ...@@ -475,7 +474,7 @@ struct lang_type
union tree_node *tags; union tree_node *tags;
char *memoized_table_entry; char *memoized_table_entry;
char *search_slot; union tree_node *search_slot;
#ifdef ONLY_INT_FIELDS #ifdef ONLY_INT_FIELDS
unsigned int mode : 8; unsigned int mode : 8;
...@@ -604,9 +603,6 @@ struct lang_type ...@@ -604,9 +603,6 @@ struct lang_type
/* Nonzero means that this signature type has a default implementation. */ /* Nonzero means that this signature type has a default implementation. */
# define HAS_DEFAULT_IMPLEMENTATION(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_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. */ /* Nonzero means that this signature contains opaque type declarations. */
#define SIGNATURE_HAS_OPAQUE_TYPEDECLS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_opaque_typedecls) #define SIGNATURE_HAS_OPAQUE_TYPEDECLS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_opaque_typedecls)
...@@ -664,8 +660,8 @@ struct lang_type ...@@ -664,8 +660,8 @@ struct lang_type
searched with TREE_CHAIN), or the first non-constructor function if searched with TREE_CHAIN), or the first non-constructor function if
there are no type conversion operators. */ there are no type conversion operators. */
#define CLASSTYPE_FIRST_CONVERSION(NODE) \ #define CLASSTYPE_FIRST_CONVERSION(NODE) \
TREE_VEC_LENGTH (CLASSTYPE_METHOD_VEC (NODE)) > 1 \ TREE_VEC_LENGTH (CLASSTYPE_METHOD_VEC (NODE)) > 2 \
? TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), 1) \ ? TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), 2) \
: NULL_TREE; : NULL_TREE;
/* Pointer from any member function to the head of the list of /* 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; ...@@ -1491,6 +1487,7 @@ extern tree __ptmf_desc_type_node, __ptmd_desc_type_node;
extern tree type_info_type_node; extern tree type_info_type_node;
extern tree class_star_type_node; extern tree class_star_type_node;
extern tree this_identifier; extern tree this_identifier;
extern tree ctor_identifier, dtor_identifier;
extern tree pfn_identifier; extern tree pfn_identifier;
extern tree index_identifier; extern tree index_identifier;
extern tree delta_identifier; extern tree delta_identifier;
...@@ -1675,6 +1672,8 @@ extern int current_function_parms_stored; ...@@ -1675,6 +1672,8 @@ extern int current_function_parms_stored;
#define THIS_NAME "this" #define THIS_NAME "this"
#define DESTRUCTOR_NAME_FORMAT "~%s" #define DESTRUCTOR_NAME_FORMAT "~%s"
#define FILE_FUNCTION_PREFIX_LEN 9 #define FILE_FUNCTION_PREFIX_LEN 9
#define CTOR_NAME "__ct"
#define DTOR_NAME "__dt"
#define IN_CHARGE_NAME "__in_chrg" #define IN_CHARGE_NAME "__in_chrg"
...@@ -2047,6 +2046,7 @@ extern tree build_ptrmemfunc_type PROTO((tree)); ...@@ -2047,6 +2046,7 @@ extern tree build_ptrmemfunc_type PROTO((tree));
/* the grokdeclarator prototype is in decl.h */ /* the grokdeclarator prototype is in decl.h */
extern int parmlist_is_exprlist PROTO((tree)); extern int parmlist_is_exprlist PROTO((tree));
extern tree xref_tag PROTO((tree, tree, tree, int)); 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 void xref_basetypes PROTO((tree, tree, tree, tree));
extern tree start_enum PROTO((tree)); extern tree start_enum PROTO((tree));
extern tree finish_enum PROTO((tree, tree)); extern tree finish_enum PROTO((tree, tree));
...@@ -2099,7 +2099,7 @@ extern void finish_builtin_type PROTO((tree, char *, tree *, int, 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_new_type PROTO((tree));
extern tree coerce_delete_type PROTO((tree)); extern tree coerce_delete_type PROTO((tree));
extern void import_export_vtable PROTO((tree, tree, int)); 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 walk_sigtables PROTO((void (*)(), void (*)()));
extern void finish_file PROTO((void)); extern void finish_file PROTO((void));
extern void warn_if_unknown_interface PROTO((tree)); extern void warn_if_unknown_interface PROTO((tree));
...@@ -2203,7 +2203,7 @@ extern void reinit_parse_for_function PROTO((void)); ...@@ -2203,7 +2203,7 @@ extern void reinit_parse_for_function PROTO((void));
extern int *init_parse PROTO((void)); extern int *init_parse PROTO((void));
extern void print_parse_statistics PROTO((void)); extern void print_parse_statistics PROTO((void));
extern void extract_interface_info 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 do_pending_inlines PROTO((void));
extern void process_next_inline PROTO((tree)); extern void process_next_inline PROTO((tree));
/* skip restore_pending_input */ /* skip restore_pending_input */
...@@ -2231,7 +2231,6 @@ extern tree make_lang_type PROTO((enum tree_code)); ...@@ -2231,7 +2231,6 @@ extern tree make_lang_type PROTO((enum tree_code));
extern void copy_decl_lang_specific PROTO((tree)); extern void copy_decl_lang_specific PROTO((tree));
extern void dump_time_statistics PROTO((void)); extern void dump_time_statistics PROTO((void));
/* extern void compiler_error PROTO((char *, HOST_WIDE_INT, HOST_WIDE_INT)); */ /* 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 *)); extern void yyerror PROTO((char *));
/* in errfn.c */ /* in errfn.c */
...@@ -2472,7 +2471,6 @@ extern tree build_ptrmemfunc PROTO((tree, tree, int)); ...@@ -2472,7 +2471,6 @@ extern tree build_ptrmemfunc PROTO((tree, tree, int));
/* in typeck2.c */ /* in typeck2.c */
extern tree error_not_base_type PROTO((tree, tree)); extern tree error_not_base_type PROTO((tree, tree));
extern tree binfo_or_else 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 readonly_error PROTO((tree, char *, int));
extern void abstract_virtuals_error PROTO((tree, tree)); extern void abstract_virtuals_error PROTO((tree, tree));
extern void signature_error PROTO((tree, tree)); extern void signature_error PROTO((tree, tree));
......
...@@ -201,6 +201,14 @@ cp_convert_to_pointer (type, expr) ...@@ -201,6 +201,14 @@ cp_convert_to_pointer (type, expr)
if (IS_AGGR_TYPE (intype)) if (IS_AGGR_TYPE (intype))
{ {
tree rval; 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); rval = build_type_conversion (CONVERT_EXPR, type, expr, 1);
if (rval) if (rval)
{ {
...@@ -774,7 +782,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl) ...@@ -774,7 +782,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
if (TYPE_HAS_CONSTRUCTOR (type) if (TYPE_HAS_CONSTRUCTOR (type)
&& ! CLASSTYPE_ABSTRACT_VIRTUALS (type) && ! CLASSTYPE_ABSTRACT_VIRTUALS (type)
&& (rval = build_method_call && (rval = build_method_call
(NULL_TREE, constructor_name_full (type), (NULL_TREE, ctor_identifier,
build_tree_list (NULL_TREE, expr), TYPE_BINFO (type), build_tree_list (NULL_TREE, expr), TYPE_BINFO (type),
LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY
| LOOKUP_ONLYCONVERTING))) | LOOKUP_ONLYCONVERTING)))
...@@ -785,7 +793,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl) ...@@ -785,7 +793,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
{ {
extern tree static_aggregates; extern tree static_aggregates;
tree t = get_temp_name (type, toplevel_bindings_p ()); 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), build_tree_list (NULL_TREE, expr),
TYPE_BINFO (type), TYPE_BINFO (type),
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
...@@ -800,7 +808,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl) ...@@ -800,7 +808,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
} }
else 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), build_tree_list (NULL_TREE, expr),
TYPE_BINFO (type), TYPE_BINFO (type),
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
...@@ -919,47 +927,9 @@ convert_to_aggr (type, expr, msgp, protect) ...@@ -919,47 +927,9 @@ convert_to_aggr (type, expr, msgp, protect)
parmlist = tree_cons (NULL_TREE, integer_zero_node, parmlist); parmlist = tree_cons (NULL_TREE, integer_zero_node, parmlist);
parmtypes = tree_cons (NULL_TREE, build_pointer_type (basetype), parmtypes); 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 /* No exact conversion was found. See if an approximate
one will do. */ one will do. */
fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0); fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);
if (TYPE_HAS_DESTRUCTOR (basetype))
fndecl = DECL_CHAIN (fndecl);
{ {
int saw_private = 0; int saw_private = 0;
...@@ -1119,7 +1089,9 @@ convert_pointer_to_real (binfo, expr) ...@@ -1119,7 +1089,9 @@ convert_pointer_to_real (binfo, expr)
binfo = NULL_TREE; 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)) if (ptr_type == TYPE_MAIN_VARIANT (intype))
return expr; return expr;
...@@ -1338,11 +1310,12 @@ cp_convert (type, expr, convtype, flags) ...@@ -1338,11 +1310,12 @@ cp_convert (type, expr, convtype, flags)
} }
if (TYPE_HAS_CONSTRUCTOR (complete_type (type))) 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), build_tree_list (NULL_TREE, e),
TYPE_BINFO (type), TYPE_BINFO (type),
(flags & LOOKUP_NORMAL) | LOOKUP_SPECULATIVELY (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)); | (conversion ? LOOKUP_NO_CONVERSION : 0));
if (ctor == error_mark_node) if (ctor == error_mark_node)
......
...@@ -757,27 +757,27 @@ grok_x_components (specs, components) ...@@ -757,27 +757,27 @@ grok_x_components (specs, components)
/* This code may be needed for UNION_TYPEs as /* This code may be needed for UNION_TYPEs as
well. */ well. */
tcode = record_type_node; tcode = record_type_node;
if (CLASSTYPE_DECLARED_CLASS(t)) if (CLASSTYPE_DECLARED_CLASS (t))
tcode = class_type_node; tcode = class_type_node;
else if (IS_SIGNATURE(t)) else if (IS_SIGNATURE (t))
tcode = signature_type_node; tcode = signature_type_node;
t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0); t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0);
if (TYPE_CONTEXT(t)) if (TYPE_CONTEXT (t))
CLASSTYPE_NO_GLOBALIZE(t) = 1; CLASSTYPE_NO_GLOBALIZE (t) = 1;
return NULL_TREE; return NULL_TREE;
break; break;
case UNION_TYPE: case UNION_TYPE:
case ENUMERAL_TYPE: case ENUMERAL_TYPE:
if (TREE_CODE(t) == UNION_TYPE) if (TREE_CODE (t) == UNION_TYPE)
tcode = union_type_node; tcode = union_type_node;
else else
tcode = enum_type_node; tcode = enum_type_node;
t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0); t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0);
if (TREE_CODE(t) == UNION_TYPE && TYPE_CONTEXT(t)) if (TREE_CODE (t) == UNION_TYPE && TYPE_CONTEXT (t))
CLASSTYPE_NO_GLOBALIZE(t) = 1; CLASSTYPE_NO_GLOBALIZE (t) = 1;
if (TREE_CODE (t) == UNION_TYPE if (TREE_CODE (t) == UNION_TYPE
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
{ {
...@@ -1233,7 +1233,11 @@ check_classfn (ctype, function) ...@@ -1233,7 +1233,11 @@ check_classfn (ctype, function)
end = TREE_VEC_END (method_vec); end = TREE_VEC_END (method_vec);
/* First suss out ctors and dtors. */ /* 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; goto got_it;
while (++methods != end) while (++methods != end)
...@@ -1295,8 +1299,8 @@ check_classfn (ctype, function) ...@@ -1295,8 +1299,8 @@ check_classfn (ctype, function)
function, ctype); function, ctype);
} }
/* If we did not find the method in the class, add it to /* If we did not find the method in the class, add it to avoid
avoid spurious errors. */ spurious errors. */
add_method (ctype, methods, function); add_method (ctype, methods, function);
return NULL_TREE; return NULL_TREE;
} }
...@@ -1381,16 +1385,6 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist) ...@@ -1381,16 +1385,6 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
DECL_CLASS_CONTEXT (value) = current_class_type; DECL_CLASS_CONTEXT (value) = current_class_type;
CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1; 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); pushdecl_class_level (value);
return value; return value;
} }
...@@ -2094,6 +2088,7 @@ get_temp_name (type, staticp) ...@@ -2094,6 +2088,7 @@ get_temp_name (type, staticp)
} }
TREE_USED (decl) = 1; TREE_USED (decl) = 1;
TREE_STATIC (decl) = staticp; TREE_STATIC (decl) = staticp;
DECL_ARTIFICIAL (decl) = 1;
/* If this is a local variable, then lay out its rtl now. /* If this is a local variable, then lay out its rtl now.
Otherwise, callers of this function are responsible for dealing Otherwise, callers of this function are responsible for dealing
...@@ -2529,7 +2524,7 @@ import_export_template (type) ...@@ -2529,7 +2524,7 @@ import_export_template (type)
} }
} }
static void static int
finish_prevtable_vardecl (prev, vars) finish_prevtable_vardecl (prev, vars)
tree prev, vars; tree prev, vars;
{ {
...@@ -2550,6 +2545,9 @@ finish_prevtable_vardecl (prev, vars) ...@@ -2550,6 +2545,9 @@ finish_prevtable_vardecl (prev, vars)
SET_CLASSTYPE_INTERFACE_KNOWN (ctype); SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method); CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method);
CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method); CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method);
#ifdef ADJUST_VTABLE_LINKAGE
ADJUST_VTABLE_LINKAGE (vars, method);
#endif
break; break;
} }
} }
...@@ -2570,14 +2568,17 @@ finish_prevtable_vardecl (prev, vars) ...@@ -2570,14 +2568,17 @@ finish_prevtable_vardecl (prev, vars)
at the top level. */ at the top level. */
build_t_desc (ctype, 1); build_t_desc (ctype, 1);
} }
return 1;
} }
static void static int
finish_vtable_vardecl (prev, vars) finish_vtable_vardecl (prev, vars)
tree prev, vars; tree prev, vars;
{ {
if (write_virtuals >= 0 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 #if 0
/* The long term plan it to make the TD entries statically initialized, /* The long term plan it to make the TD entries statically initialized,
...@@ -2622,29 +2623,33 @@ finish_vtable_vardecl (prev, vars) ...@@ -2622,29 +2623,33 @@ finish_vtable_vardecl (prev, vars)
#endif /* DWARF_DEBUGGING_INFO */ #endif /* DWARF_DEBUGGING_INFO */
rest_of_decl_compilation (vars, NULL_PTR, 1, 1); rest_of_decl_compilation (vars, NULL_PTR, 1, 1);
return 1;
} }
else if (! TREE_USED (vars)) else if (! TREE_USED (vars))
/* We don't know what to do with this one yet. */ /* We don't know what to do with this one yet. */
return; return 0;
/* We know that PREV must be non-zero here. */ /* We know that PREV must be non-zero here. */
TREE_CHAIN (prev) = TREE_CHAIN (vars); TREE_CHAIN (prev) = TREE_CHAIN (vars);
return 0;
} }
static void static int
prune_vtable_vardecl (prev, vars) prune_vtable_vardecl (prev, vars)
tree prev, vars; tree prev, vars;
{ {
/* We know that PREV must be non-zero here. */ /* We know that PREV must be non-zero here. */
TREE_CHAIN (prev) = TREE_CHAIN (vars); TREE_CHAIN (prev) = TREE_CHAIN (vars);
return 1;
} }
void int
walk_vtables (typedecl_fn, vardecl_fn) walk_vtables (typedecl_fn, vardecl_fn)
register void (*typedecl_fn)(); register void (*typedecl_fn)();
register void (*vardecl_fn)(); register int (*vardecl_fn)();
{ {
tree prev, vars; tree prev, vars;
int flag = 0;
for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars)) for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars))
{ {
...@@ -2652,7 +2657,8 @@ walk_vtables (typedecl_fn, vardecl_fn) ...@@ -2652,7 +2657,8 @@ walk_vtables (typedecl_fn, vardecl_fn)
if (TREE_CODE (vars) == VAR_DECL && DECL_VIRTUAL_P (vars)) 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) if (prev && TREE_CHAIN (prev) != vars)
continue; continue;
...@@ -2667,6 +2673,8 @@ walk_vtables (typedecl_fn, vardecl_fn) ...@@ -2667,6 +2673,8 @@ walk_vtables (typedecl_fn, vardecl_fn)
prev = vars; prev = vars;
} }
return flag;
} }
static void static void
...@@ -2910,7 +2918,7 @@ finish_file () ...@@ -2910,7 +2918,7 @@ finish_file ()
expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors), expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
NULL_TREE)); NULL_TREE));
expand_end_bindings (getdecls(), 1, 0); expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0); poplevel (1, 0, 0);
pop_momentary (); pop_momentary ();
...@@ -3027,7 +3035,7 @@ finish_file () ...@@ -3027,7 +3035,7 @@ finish_file ()
expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors), expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
NULL_TREE)); NULL_TREE));
expand_end_bindings (getdecls(), 1, 0); expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0); poplevel (1, 0, 0);
pop_momentary (); pop_momentary ();
...@@ -3107,7 +3115,7 @@ finish_file () ...@@ -3107,7 +3115,7 @@ finish_file ()
SET_DECL_ARTIFICIAL (vars); SET_DECL_ARTIFICIAL (vars);
pushdecl (vars); pushdecl (vars);
walk_vtables ((void (*)())0, finish_vtable_vardecl); reconsider |= walk_vtables ((void (*)())0, finish_vtable_vardecl);
while (*p) while (*p)
{ {
...@@ -3314,6 +3322,8 @@ build_expr_from_tree (t) ...@@ -3314,6 +3322,8 @@ build_expr_from_tree (t)
case TRUTH_NOT_EXPR: case TRUTH_NOT_EXPR:
case ADDR_EXPR: case ADDR_EXPR:
case CONVERT_EXPR: /* Unary + */ case CONVERT_EXPR: /* Unary + */
if (TREE_TYPE (t))
return t;
return build_x_unary_op (TREE_CODE (t), return build_x_unary_op (TREE_CODE (t),
build_expr_from_tree (TREE_OPERAND (t, 0))); build_expr_from_tree (TREE_OPERAND (t, 0)));
...@@ -3472,6 +3482,9 @@ build_expr_from_tree (t) ...@@ -3472,6 +3482,9 @@ build_expr_from_tree (t)
(build_expr_from_tree (TREE_OPERAND (t, 0)), (build_expr_from_tree (TREE_OPERAND (t, 0)),
TREE_OPERAND (t, 1), NULL_TREE, 1); TREE_OPERAND (t, 1), NULL_TREE, 1);
case THROW_EXPR:
return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0)));
default: default:
return t; return t;
} }
...@@ -3599,6 +3612,7 @@ void ...@@ -3599,6 +3612,7 @@ void
do_namespace_alias (alias, namespace) do_namespace_alias (alias, namespace)
tree alias, namespace; tree alias, namespace;
{ {
sorry ("namespace alias");
} }
tree tree
...@@ -3651,6 +3665,7 @@ void ...@@ -3651,6 +3665,7 @@ void
do_using_directive (namespace) do_using_directive (namespace)
tree namespace; tree namespace;
{ {
sorry ("using directive");
} }
void void
......
...@@ -543,7 +543,7 @@ ident_fndecl (t) ...@@ -543,7 +543,7 @@ ident_fndecl (t)
#endif #endif
#define GLOBAL_IORD_P(NODE) \ #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 void
dump_global_iord (t) dump_global_iord (t)
...@@ -581,12 +581,9 @@ dump_decl (t, v) ...@@ -581,12 +581,9 @@ dump_decl (t, v)
case TYPE_DECL: case TYPE_DECL:
{ {
/* Don't say 'typedef class A' */ /* Don't say 'typedef class A' */
tree type = TREE_TYPE (t); if (DECL_ARTIFICIAL (t))
if (((IS_AGGR_TYPE (type) && ! TYPE_PTRMEMFUNC_P (type))
|| TREE_CODE (type) == ENUMERAL_TYPE)
&& type == TYPE_MAIN_VARIANT (type))
{ {
dump_type (type, v); dump_type (TREE_TYPE (t), v);
break; break;
} }
} }
...@@ -1087,7 +1084,7 @@ dump_expr (t, nop) ...@@ -1087,7 +1084,7 @@ dump_expr (t, nop)
args = TREE_CHAIN (args); args = TREE_CHAIN (args);
} }
dump_expr (fn, 0); dump_expr (fn, 0);
OB_PUTC('('); OB_PUTC ('(');
dump_expr_list (args); dump_expr_list (args);
OB_PUTC (')'); OB_PUTC (')');
} }
......
...@@ -1398,7 +1398,7 @@ expand_builtin_throw () ...@@ -1398,7 +1398,7 @@ expand_builtin_throw ()
/* Fall into epilogue to unwind prologue. */ /* Fall into epilogue to unwind prologue. */
} }
expand_end_bindings (getdecls(), 1, 0); expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0); poplevel (1, 0, 0);
pop_momentary (); pop_momentary ();
...@@ -1626,7 +1626,7 @@ start_anon_func () ...@@ -1626,7 +1626,7 @@ start_anon_func ()
void void
end_anon_func () end_anon_func ()
{ {
expand_end_bindings (getdecls(), 1, 0); expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0); poplevel (1, 0, 0);
pop_momentary (); pop_momentary ();
...@@ -1809,6 +1809,8 @@ build_throw (e) ...@@ -1809,6 +1809,8 @@ build_throw (e)
{ {
if (e != error_mark_node) 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); e = build1 (THROW_EXPR, void_type_node, e);
TREE_SIDE_EFFECTS (e) = 1; TREE_SIDE_EFFECTS (e) = 1;
TREE_USED (e) = 1; TREE_USED (e) = 1;
......
...@@ -366,6 +366,9 @@ do_case (start, end) ...@@ -366,6 +366,9 @@ do_case (start, end)
{ {
tree value1 = NULL_TREE, value2 = NULL_TREE, label; 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) if (end && pedantic)
pedwarn ("ANSI C++ forbids range expressions in switch statement"); pedwarn ("ANSI C++ forbids range expressions in switch statement");
......
...@@ -1226,22 +1226,22 @@ stands. ...@@ -1226,22 +1226,22 @@ stands.
Only exact type matching or reference matching of throw types works when 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, -fno-rtti is used. Only works on a SPARC (like Suns), i386, arm,
rs6000, PowerPC, Alpha, mips and VAX machines. Partial support is in rs6000, PowerPC, Alpha, mips, VAX, and m68k machines. Partial support
for all other machines, but a stack unwinder called __unwind_function is in for all other machines, but a stack unwinder called
has to be written, and added to libgcc2 for them. The new EH code __unwind_function has to be written, and added to libgcc2 for them. The
doesn't rely upon the __unwind_function for C++ code, instead it creates new EH code doesn't rely upon the __unwind_function for C++ code,
per function unwinders right inside the function, unfortunately, on many instead it creates per function unwinders right inside the function,
platforms the definition of RETURN_ADDR_RTX in the tm.h file for the unfortunately, on many platforms the definition of RETURN_ADDR_RTX in
machine port is wrong. The HPPA has a brain dead abi that prevents the tm.h file for the machine port is wrong. The HPPA has a brain dead
exception handling from just working. See below for details on abi that prevents exception handling from just working. See below for
__unwind_function. Don't expect exception handling to work right if you details on __unwind_function. Don't expect exception handling to work
optimize, in fact the compiler will probably core dump. RTL_EXPRs for right if you optimize, in fact the compiler will probably core dump.
EH cond variables for && and || exprs should probably be wrapped in RTL_EXPRs for EH cond variables for && and || exprs should probably be
UNSAVE_EXPRs, and RTL_EXPRs tweaked so that they can be unsaved, and the wrapped in UNSAVE_EXPRs, and RTL_EXPRs tweaked so that they can be
UNSAVE_EXPR code should be in the backend, or alternatively, UNSAVE_EXPR unsaved, and the UNSAVE_EXPR code should be in the backend, or
should be ripped out and exactly one finalization allowed to be expanded alternatively, UNSAVE_EXPR should be ripped out and exactly one
by the backend. I talked with kenner about this, and we have to allow finalization allowed to be expanded by the backend. I talked with
multiple expansions. kenner about this, and we have to allow multiple expansions.
We only do pointer conversions on exception matching a la 15.3 p2 case 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 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) ...@@ -837,6 +837,11 @@ yyprint (file, yychar, yylval)
case SCSPEC: case SCSPEC:
case PRE_PARSED_CLASS_DECL: case PRE_PARSED_CLASS_DECL:
t = yylval.ttype; 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); my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);
if (IDENTIFIER_POINTER (t)) if (IDENTIFIER_POINTER (t))
fprintf (file, " `%s'", IDENTIFIER_POINTER (t)); fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
...@@ -1076,7 +1081,7 @@ set_typedecl_interface_info (prev, vars) ...@@ -1076,7 +1081,7 @@ set_typedecl_interface_info (prev, vars)
= interface_strcmp (FILE_NAME_NONDIRECTORY (DECL_SOURCE_FILE (vars))); = interface_strcmp (FILE_NAME_NONDIRECTORY (DECL_SOURCE_FILE (vars)));
} }
void int
set_vardecl_interface_info (prev, vars) set_vardecl_interface_info (prev, vars)
tree prev, vars; tree prev, vars;
{ {
...@@ -1090,7 +1095,9 @@ set_vardecl_interface_info (prev, vars) ...@@ -1090,7 +1095,9 @@ set_vardecl_interface_info (prev, vars)
CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1; CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type); DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
TREE_PUBLIC (vars) = 1; TREE_PUBLIC (vars) = 1;
return 1;
} }
return 0;
} }
/* Called from the top level: if there are any pending inlines to /* Called from the top level: if there are any pending inlines to
...@@ -1683,6 +1690,7 @@ cons_up_default_function (type, full_name, kind) ...@@ -1683,6 +1690,7 @@ cons_up_default_function (type, full_name, kind)
} }
#endif #endif
#if 0
if (CLASSTYPE_INTERFACE_KNOWN (type)) if (CLASSTYPE_INTERFACE_KNOWN (type))
{ {
DECL_INTERFACE_KNOWN (fn) = 1; DECL_INTERFACE_KNOWN (fn) = 1;
...@@ -1690,6 +1698,7 @@ cons_up_default_function (type, full_name, kind) ...@@ -1690,6 +1698,7 @@ cons_up_default_function (type, full_name, kind)
&& flag_implement_inlines); && flag_implement_inlines);
} }
else else
#endif
DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_NOT_REALLY_EXTERN (fn) = 1;
mark_inline_for_output (fn); mark_inline_for_output (fn);
...@@ -1986,7 +1995,7 @@ check_newline () ...@@ -1986,7 +1995,7 @@ check_newline ()
goto skipline; goto skipline;
} }
main_filename = TREE_STRING_POINTER (yylval.ttype); main_filename = TREE_STRING_POINTER (yylval.ttype);
c = getch(); c = getch ();
put_back (c); put_back (c);
} }
...@@ -2063,7 +2072,7 @@ check_newline () ...@@ -2063,7 +2072,7 @@ check_newline ()
goto skipline; goto skipline;
} }
main_filename = TREE_STRING_POINTER (yylval.ttype); main_filename = TREE_STRING_POINTER (yylval.ttype);
c = getch(); c = getch ();
put_back (c); put_back (c);
} }
...@@ -2683,7 +2692,7 @@ see_typename () ...@@ -2683,7 +2692,7 @@ see_typename ()
{ {
looking_for_typename = 1; looking_for_typename = 1;
if (yychar < 0) if (yychar < 0)
if ((yychar = yylex()) < 0) yychar = 0; if ((yychar = yylex ()) < 0) yychar = 0;
looking_for_typename = 0; looking_for_typename = 0;
if (yychar == IDENTIFIER) if (yychar == IDENTIFIER)
{ {
...@@ -2742,7 +2751,7 @@ do_identifier (token, parsing) ...@@ -2742,7 +2751,7 @@ do_identifier (token, parsing)
/* Remember that this name has been used in the class definition, as per /* Remember that this name has been used in the class definition, as per
[class.scope0] */ [class.scope0] */
if (id && current_class_type if (id && current_class_type && parsing
&& TYPE_BEING_DEFINED (current_class_type) && TYPE_BEING_DEFINED (current_class_type)
&& ! IDENTIFIER_CLASS_VALUE (token)) && ! IDENTIFIER_CLASS_VALUE (token))
pushdecl_class_level (id); pushdecl_class_level (id);
...@@ -3238,6 +3247,14 @@ real_yylex () ...@@ -3238,6 +3247,14 @@ real_yylex ()
token_buffer[0] = '^'; token_buffer[0] = '^';
token_buffer[1] = 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; value = (int) ptr->token;
} }
...@@ -4037,7 +4054,7 @@ real_yylex () ...@@ -4037,7 +4054,7 @@ real_yylex ()
skipnewline: skipnewline:
c = getch (); c = getch ();
if (c == EOF) { if (c == EOF) {
error("Unterminated string"); error ("Unterminated string");
break; break;
} }
} }
...@@ -4383,7 +4400,7 @@ build_lang_decl (code, name, type) ...@@ -4383,7 +4400,7 @@ build_lang_decl (code, name, type)
#endif #endif
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_decl] += 1; 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 #endif
return t; return t;
...@@ -4480,7 +4497,7 @@ make_lang_type (code) ...@@ -4480,7 +4497,7 @@ make_lang_type (code)
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_type] += 1; 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 #endif
return t; return t;
...@@ -4509,7 +4526,7 @@ copy_decl_lang_specific (decl) ...@@ -4509,7 +4526,7 @@ copy_decl_lang_specific (decl)
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_decl] += 1; 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 #endif
} }
...@@ -4549,32 +4566,6 @@ compiler_error (s, v, v2) ...@@ -4549,32 +4566,6 @@ compiler_error (s, v, v2)
sprintf (buf, s, v, v2); sprintf (buf, s, v, v2);
error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf); 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 void
yyerror (string) yyerror (string)
......
...@@ -91,10 +91,12 @@ do_inline_function_hair (type, friend_list) ...@@ -91,10 +91,12 @@ do_inline_function_hair (type, friend_list)
if (method && TREE_CODE (method) == TREE_VEC) 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); method = TREE_VEC_ELT (method, 0);
else else
method = TREE_VEC_ELT (method, 1); method = TREE_VEC_ELT (method, 2);
} }
while (method) while (method)
...@@ -1277,9 +1279,26 @@ build_opfncall (code, flags, xarg1, xarg2, arg3) ...@@ -1277,9 +1279,26 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
build_tree_list (NULL_TREE, xarg1), build_tree_list (NULL_TREE, xarg1),
flags & LOOKUP_COMPLAIN, flags & LOOKUP_COMPLAIN,
(struct candidate *)0); (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 rval = build_method_call
(build_indirect_ref (build1 (NOP_EXPR, TREE_TYPE (xarg1), (build_indirect_ref (build1 (NOP_EXPR, arg1,
error_mark_node), error_mark_node),
NULL_PTR), NULL_PTR),
fnname, tree_cons (NULL_TREE, xarg1, fnname, tree_cons (NULL_TREE, xarg1,
...@@ -1826,7 +1845,7 @@ make_thunk (function, delta) ...@@ -1826,7 +1845,7 @@ make_thunk (function, delta)
thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id); thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);
if (thunk && TREE_CODE (thunk) != THUNK_DECL) 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; IDENTIFIER_GLOBAL_VALUE (thunk_id) = thunk = NULL_TREE;
} }
if (thunk == NULL_TREE) if (thunk == NULL_TREE)
......
...@@ -499,10 +499,10 @@ datadef: ...@@ -499,10 +499,10 @@ datadef:
| typed_declspecs declarator ';' | typed_declspecs declarator ';'
{ tree d, specs, attrs; { tree d, specs, attrs;
split_specs_attrs ($1, &specs, &attrs); split_specs_attrs ($1, &specs, &attrs);
note_list_got_semicolon (specs);
d = start_decl ($<ttype>2, specs, 0, NULL_TREE); d = start_decl ($<ttype>2, specs, 0, NULL_TREE);
cplus_decl_attributes (d, NULL_TREE, attrs); cplus_decl_attributes (d, NULL_TREE, attrs);
cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0); cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
note_list_got_semicolon ($<ttype>$);
} }
| declmods ';' | declmods ';'
{ pedwarn ("empty declaration"); } { pedwarn ("empty declaration"); }
...@@ -1990,7 +1990,9 @@ pending_inlines: ...@@ -1990,7 +1990,9 @@ pending_inlines:
| pending_inlines fn.defpen maybe_return_init ctor_initializer_opt | pending_inlines fn.defpen maybe_return_init ctor_initializer_opt
compstmt_or_error 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); process_next_inline ($2);
} }
| pending_inlines fn.defpen maybe_return_init function_try_block | pending_inlines fn.defpen maybe_return_init function_try_block
...@@ -2108,7 +2110,19 @@ named_class_head_sans_basetype_defn: ...@@ -2108,7 +2110,19 @@ named_class_head_sans_basetype_defn:
named_complex_class_head_sans_basetype: named_complex_class_head_sans_basetype:
aggr nested_name_specifier identifier 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 | aggr template_type
{ current_aggr = $$; $$ = $2; } { current_aggr = $$; $$ = $2; }
| aggr nested_name_specifier template_type | aggr nested_name_specifier template_type
...@@ -3519,8 +3533,10 @@ function_try_block: ...@@ -3519,8 +3533,10 @@ function_try_block:
expand_start_all_catch (); } expand_start_all_catch (); }
handler_seq handler_seq
{ {
int nested = (hack_decl_function_context
(current_function_decl) != NULL_TREE);
expand_end_all_catch (); expand_end_all_catch ();
finish_function (lineno, (int)$3, 0); finish_function (lineno, (int)$3, nested);
} }
; ;
...@@ -3820,6 +3836,9 @@ bad_parm: ...@@ -3820,6 +3836,9 @@ bad_parm:
| notype_declarator | notype_declarator
{ {
error ("type specifier omitted for parameter"); 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, $$); $$ = build_tree_list (integer_type_node, $$);
} }
; ;
......
/* Handle parameterized types (templates) for GNU C++. /* Handle parameterized types (templates) for GNU C++.
Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. 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. This file is part of GNU CC.
...@@ -233,6 +234,9 @@ push_template_decl (decl) ...@@ -233,6 +234,9 @@ push_template_decl (decl)
{ {
if (TREE_CODE (decl) == TYPE_DECL) if (TREE_CODE (decl) == TYPE_DECL)
tmpl = CLASSTYPE_TI_TEMPLATE (TREE_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 else
tmpl = DECL_TI_TEMPLATE (decl); tmpl = DECL_TI_TEMPLATE (decl);
} }
...@@ -475,12 +479,10 @@ mangle_class_name_for_template (name, parms, arglist) ...@@ -475,12 +479,10 @@ mangle_class_name_for_template (name, parms, arglist)
int i, nparms; int i, nparms;
if (!scratch_firstobj) if (!scratch_firstobj)
{ gcc_obstack_init (&scratch_obstack);
gcc_obstack_init (&scratch_obstack);
scratch_firstobj = obstack_alloc (&scratch_obstack, 1);
}
else else
obstack_free (&scratch_obstack, scratch_firstobj); obstack_free (&scratch_obstack, scratch_firstobj);
scratch_firstobj = obstack_alloc (&scratch_obstack, 1);
#if 0 #if 0
#define buflen sizeof(buf) #define buflen sizeof(buf)
...@@ -629,12 +631,6 @@ lookup_template_class (d1, arglist, in_decl) ...@@ -629,12 +631,6 @@ lookup_template_class (d1, arglist, in_decl)
return error_mark_node; 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)) if (PRIMARY_TEMPLATE_P (template))
{ {
parmlist = DECL_TEMPLATE_PARMS (template); parmlist = DECL_TEMPLATE_PARMS (template);
...@@ -675,7 +671,7 @@ lookup_template_class (d1, arglist, in_decl) ...@@ -675,7 +671,7 @@ lookup_template_class (d1, arglist, in_decl)
IDENTIFIER_TEMPLATE (id) = d1; IDENTIFIER_TEMPLATE (id) = d1;
maybe_push_to_top_level (uses_template_parms (arglist)); 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 (); pop_from_top_level ();
} }
else else
...@@ -689,7 +685,7 @@ lookup_template_class (d1, arglist, in_decl) ...@@ -689,7 +685,7 @@ lookup_template_class (d1, arglist, in_decl)
{ {
tree save_parms = current_template_parms; tree save_parms = current_template_parms;
current_template_parms = NULL_TREE; 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; current_template_parms = save_parms;
} }
else else
...@@ -978,7 +974,7 @@ tree ...@@ -978,7 +974,7 @@ tree
instantiate_class_template (type) instantiate_class_template (type)
tree 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) if (type == error_mark_node)
return error_mark_node; return error_mark_node;
...@@ -1060,7 +1056,6 @@ instantiate_class_template (type) ...@@ -1060,7 +1056,6 @@ instantiate_class_template (type)
CLASSTYPE_LOCAL_TYPEDECLS (type) = CLASSTYPE_LOCAL_TYPEDECLS (pattern); CLASSTYPE_LOCAL_TYPEDECLS (type) = CLASSTYPE_LOCAL_TYPEDECLS (pattern);
field_chain = &TYPE_FIELDS (type); field_chain = &TYPE_FIELDS (type);
tag_chain = &CLASSTYPE_TAGS (type);
for (t = CLASSTYPE_TAGS (pattern); t; t = TREE_CHAIN (t)) for (t = CLASSTYPE_TAGS (pattern); t; t = TREE_CHAIN (t))
{ {
...@@ -1068,15 +1063,13 @@ instantiate_class_template (type) ...@@ -1068,15 +1063,13 @@ instantiate_class_template (type)
tree tag = TREE_VALUE (t); tree tag = TREE_VALUE (t);
tree newtag; tree newtag;
/* These will add themselves to CLASSTYPE_TAGS for the new type. */
if (TREE_CODE (tag) == ENUMERAL_TYPE) if (TREE_CODE (tag) == ENUMERAL_TYPE)
newtag = start_enum (name); newtag = start_enum (name);
else else
newtag = tsubst (tag, &TREE_VEC_ELT (args, 0), newtag = tsubst (tag, &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args), NULL_TREE); 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) if (TREE_CODE (tag) == ENUMERAL_TYPE)
{ {
tree e, values = NULL_TREE, *last = &values; tree e, values = NULL_TREE, *last = &values;
...@@ -1124,16 +1117,30 @@ instantiate_class_template (type) ...@@ -1124,16 +1117,30 @@ instantiate_class_template (type)
TYPE_METHODS (type) = tsubst_chain (TYPE_METHODS (pattern), args); TYPE_METHODS (type) = tsubst_chain (TYPE_METHODS (pattern), args);
DECL_FRIENDLIST (TYPE_MAIN_DECL (type)) DECL_FRIENDLIST (TYPE_MAIN_DECL (type))
= tsubst_chain (DECL_FRIENDLIST (TYPE_MAIN_DECL (pattern)), args); = tsubst (DECL_FRIENDLIST (TYPE_MAIN_DECL (pattern)),
CLASSTYPE_FRIEND_CLASSES (type) &TREE_VEC_ELT (args, 0), TREE_VEC_LENGTH (args), NULL_TREE);
= tsubst_chain (CLASSTYPE_FRIEND_CLASSES (pattern), args);
{ {
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); TREE_VEC_LENGTH (args), NULL_TREE);
for (; d; d = TREE_CHAIN (d)) 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); TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
...@@ -1781,6 +1788,11 @@ tsubst (t, args, nargs, in_decl) ...@@ -1781,6 +1788,11 @@ tsubst (t, args, nargs, in_decl)
(CALL_EXPR, tsubst (TREE_OPERAND (t, 0), 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); 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: default:
sorry ("use of `%s' in template", sorry ("use of `%s' in template",
tree_code_name [(int) TREE_CODE (t)]); tree_code_name [(int) TREE_CODE (t)]);
...@@ -1866,6 +1878,7 @@ tsubst_copy (t, args, nargs, in_decl) ...@@ -1866,6 +1878,7 @@ tsubst_copy (t, args, nargs, in_decl)
case CONVERT_EXPR: /* Unary + */ case CONVERT_EXPR: /* Unary + */
case SIZEOF_EXPR: case SIZEOF_EXPR:
case ARROW_EXPR: case ARROW_EXPR:
case THROW_EXPR:
return build1 return build1
(code, NULL_TREE, (code, NULL_TREE,
tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl)); tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl));
...@@ -1928,7 +1941,7 @@ tsubst_copy (t, args, nargs, in_decl) ...@@ -1928,7 +1941,7 @@ tsubst_copy (t, args, nargs, in_decl)
if (TREE_CODE (name) == BIT_NOT_EXPR) if (TREE_CODE (name) == BIT_NOT_EXPR)
{ {
name = tsubst_copy (TREE_OPERAND (name, 0), args, nargs, in_decl); 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 else if (TREE_CODE (name) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR) && TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR)
...@@ -1936,7 +1949,7 @@ tsubst_copy (t, args, nargs, in_decl) ...@@ -1936,7 +1949,7 @@ tsubst_copy (t, args, nargs, in_decl)
tree base = tsubst_copy (TREE_OPERAND (name, 0), args, nargs, in_decl); tree base = tsubst_copy (TREE_OPERAND (name, 0), args, nargs, in_decl);
name = TREE_OPERAND (name, 1); name = TREE_OPERAND (name, 1);
name = tsubst_copy (TREE_OPERAND (name, 0), args, nargs, in_decl); 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); name = build_nt (SCOPE_REF, base, name);
} }
else else
...@@ -2915,7 +2928,7 @@ instantiate_decl (d) ...@@ -2915,7 +2928,7 @@ instantiate_decl (d)
warn_if_unknown_interface (pattern); warn_if_unknown_interface (pattern);
} }
if (at_eof) if (at_eof && ! DECL_INLINE (d))
import_export_decl (d); import_export_decl (d);
} }
......
...@@ -71,7 +71,7 @@ static int debug_yychar (); ...@@ -71,7 +71,7 @@ static int debug_yychar ();
void void
init_spew () init_spew ()
{ {
gcc_obstack_init(&token_obstack); gcc_obstack_init (&token_obstack);
} }
#ifdef SPEW_DEBUG #ifdef SPEW_DEBUG
...@@ -81,7 +81,7 @@ init_spew () ...@@ -81,7 +81,7 @@ init_spew ()
static int static int
num_tokens () num_tokens ()
{ {
return (obstack_object_size(&token_obstack)/sizeof(struct token)) return (obstack_object_size (&token_obstack) / sizeof (struct token))
- first_token; - first_token;
} }
...@@ -92,8 +92,8 @@ nth_token (n) ...@@ -92,8 +92,8 @@ nth_token (n)
{ {
/* could just have this do slurp_ implicitly, but this way is easier /* could just have this do slurp_ implicitly, but this way is easier
* to debug... */ * to debug... */
my_friendly_assert (n < num_tokens(), 298); my_friendly_assert (n < num_tokens (), 298);
return ((struct token*)obstack_base(&token_obstack))+n+first_token; return ((struct token*)obstack_base (&token_obstack)) + n + first_token;
} }
/* Add a token to the token fifo. */ /* Add a token to the token fifo. */
...@@ -101,16 +101,16 @@ static void ...@@ -101,16 +101,16 @@ static void
add_token (t) add_token (t)
struct 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. */ /* Consume the next token out of the fifo. */
static void 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; first_token = 0;
} }
else else
...@@ -121,15 +121,15 @@ consume_token() ...@@ -121,15 +121,15 @@ consume_token()
/* ...otherwise use macros. */ /* ...otherwise use macros. */
#define num_tokens() \ #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) \ #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() \ #define consume_token() \
(num_tokens() == 1 \ (num_tokens () == 1 \
? (obstack_free (&token_obstack, obstack_base (&token_obstack)), \ ? (obstack_free (&token_obstack, obstack_base (&token_obstack)), \
(first_token = 0)) \ (first_token = 0)) \
: first_token++) : first_token++)
...@@ -158,11 +158,11 @@ scan_tokens (n) ...@@ -158,11 +158,11 @@ scan_tokens (n)
goto pad_tokens; 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 = ((struct token *)obstack_next_free (&token_obstack))-1;
tmp->yychar = real_yylex(); tmp->yychar = real_yylex ();
tmp->end_of_file = end_of_file; tmp->end_of_file = end_of_file;
tmp->yylval = yylval; tmp->yylval = yylval;
end_of_file = 0; end_of_file = 0;
...@@ -173,7 +173,7 @@ scan_tokens (n) ...@@ -173,7 +173,7 @@ scan_tokens (n)
pad_tokens: 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 = ((struct token *)obstack_next_free (&token_obstack))-1;
tmp->yychar = EMPTY; tmp->yychar = EMPTY;
tmp->end_of_file = 0; tmp->end_of_file = 0;
...@@ -216,14 +216,14 @@ tree got_scope; ...@@ -216,14 +216,14 @@ tree got_scope;
tree got_object; tree got_object;
int int
peekyylex() peekyylex ()
{ {
scan_tokens (0); scan_tokens (0);
return nth_token (0)->yychar; return nth_token (0)->yychar;
} }
int int
yylex() yylex ()
{ {
struct token tmp_token; struct token tmp_token;
tree trrr; tree trrr;
...@@ -233,14 +233,14 @@ yylex() ...@@ -233,14 +233,14 @@ yylex()
if (spew_debug) if (spew_debug)
{ {
yylex_ctr ++; yylex_ctr ++;
fprintf(stderr, "\t\t## %d ##",yylex_ctr); fprintf (stderr, "\t\t## %d ##", yylex_ctr);
} }
#endif #endif
/* if we've got tokens, send them */ /* 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. /* 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 If we don't find it in CURRENT_OBSTACK's current or immediately
...@@ -258,13 +258,13 @@ yylex() ...@@ -258,13 +258,13 @@ yylex()
tmp_token.yychar = real_yylex (); tmp_token.yychar = real_yylex ();
tmp_token.yylval = yylval; tmp_token.yylval = yylval;
tmp_token.end_of_file = end_of_file; 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 /* 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 * have to do is send them back up, but some of them are needed to
* figure out local context. */ * figure out local context. */
switch(tmp_token.yychar) switch (tmp_token.yychar)
{ {
case EMPTY: case EMPTY:
/* This is a lexical no-op. */ /* This is a lexical no-op. */
...@@ -341,7 +341,7 @@ yylex() ...@@ -341,7 +341,7 @@ yylex()
break; break;
case AGGR: case AGGR:
*nth_token(0) = tmp_token; *nth_token (0) = tmp_token;
do_aggr (); do_aggr ();
/* fall through to output... */ /* fall through to output... */
case ENUM: case ENUM:
...@@ -349,7 +349,7 @@ yylex() ...@@ -349,7 +349,7 @@ yylex()
looking_for_typename = 1; looking_for_typename = 1;
/* fall through... */ /* fall through... */
default: default:
consume_token(); consume_token ();
} }
got_object = NULL_TREE; got_object = NULL_TREE;
...@@ -358,7 +358,7 @@ yylex() ...@@ -358,7 +358,7 @@ yylex()
end_of_file = tmp_token.end_of_file; end_of_file = tmp_token.end_of_file;
#ifdef SPEW_DEBUG #ifdef SPEW_DEBUG
if (spew_debug) if (spew_debug)
debug_yychar(yychar); debug_yychar (yychar);
#endif #endif
return yychar; return yychar;
} }
...@@ -423,7 +423,7 @@ debug_yychar (yy) ...@@ -423,7 +423,7 @@ debug_yychar (yy)
int i; int i;
if(yy<256) { if (yy<256) {
fprintf (stderr, "<%d: %c >\n", yy, yy); fprintf (stderr, "<%d: %c >\n", yy, yy);
return 0; return 0;
} }
......
...@@ -800,9 +800,9 @@ layout_basetypes (rec, binfos) ...@@ -800,9 +800,9 @@ layout_basetypes (rec, binfos)
vbase_decls = decl; vbase_decls = decl;
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype) 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"); "destructor `%s' non-virtual");
warning ("in inheritance relationship `%s: virtual %s'", warning ("in inheritance relationship `%s: virtual %s'",
TYPE_NAME_STRING (rec), TYPE_NAME_STRING (rec),
...@@ -827,9 +827,9 @@ layout_basetypes (rec, binfos) ...@@ -827,9 +827,9 @@ layout_basetypes (rec, binfos)
claim it as theirs and explain exactly what circumstances claim it as theirs and explain exactly what circumstances
warrant the warning. */ warrant the warning. */
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype) 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"); "destructor `%s' non-virtual");
warning ("in inheritance relationship `%s:%s %s'", warning ("in inheritance relationship `%s:%s %s'",
TYPE_NAME_STRING (rec), TYPE_NAME_STRING (rec),
...@@ -1950,7 +1950,8 @@ min_tree_cons (purpose, value, chain) ...@@ -1950,7 +1950,8 @@ min_tree_cons (purpose, value, chain)
register struct obstack *ambient_obstack = current_obstack; register struct obstack *ambient_obstack = current_obstack;
current_obstack = &permanent_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; current_obstack = ambient_obstack;
return node; return node;
} }
......
...@@ -1767,6 +1767,12 @@ build_component_ref (datum, component, basetype_path, protect) ...@@ -1767,6 +1767,12 @@ build_component_ref (datum, component, basetype_path, protect)
basetype = TREE_TYPE (datum); basetype = TREE_TYPE (datum);
code = TREE_CODE (basetype); 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. */ /* First, see if there is a field or component with name COMPONENT. */
if (TREE_CODE (component) == TREE_LIST) if (TREE_CODE (component) == TREE_LIST)
...@@ -1803,7 +1809,7 @@ build_component_ref (datum, component, basetype_path, protect) ...@@ -1803,7 +1809,7 @@ build_component_ref (datum, component, basetype_path, protect)
cp_error ("type `%T' has no destructor", basetype); cp_error ("type `%T' has no destructor", basetype);
return error_mark_node; 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. */ /* Look up component name in the structure type definition. */
...@@ -1905,7 +1911,8 @@ build_component_ref (datum, component, basetype_path, protect) ...@@ -1905,7 +1911,8 @@ build_component_ref (datum, component, basetype_path, protect)
{ {
tree context = DECL_FIELD_CONTEXT (field); tree context = DECL_FIELD_CONTEXT (field);
tree base = context; 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); base = TYPE_CONTEXT (base);
} }
...@@ -1935,7 +1942,7 @@ build_component_ref (datum, component, basetype_path, protect) ...@@ -1935,7 +1942,7 @@ build_component_ref (datum, component, basetype_path, protect)
basetype = base; basetype = base;
/* Handle things from anon unions here... */ /* 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 subfield = lookup_anon_field (basetype, context);
tree subdatum = build_component_ref (datum, subfield, tree subdatum = build_component_ref (datum, subfield,
...@@ -2231,6 +2238,23 @@ build_x_function_call (function, params, decl) ...@@ -2231,6 +2238,23 @@ build_x_function_call (function, params, decl)
return build_min_nt (CALL_EXPR, function, params, 0); return build_min_nt (CALL_EXPR, function, params, 0);
type = TREE_TYPE (function); 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 is_method = ((TREE_CODE (function) == TREE_LIST
&& current_class_type != NULL_TREE && current_class_type != NULL_TREE
&& IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (function)) == function) && IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (function)) == function)
...@@ -2238,6 +2262,11 @@ build_x_function_call (function, params, decl) ...@@ -2238,6 +2262,11 @@ build_x_function_call (function, params, decl)
|| TREE_CODE (type) == METHOD_TYPE || TREE_CODE (type) == METHOD_TYPE
|| TYPE_PTRMEMFUNC_P (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. */ /* Handle methods, friends, and overloaded functions, respectively. */
if (is_method) if (is_method)
{ {
...@@ -2712,9 +2741,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) ...@@ -2712,9 +2741,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
{ {
if (fndecl) if (fndecl)
{ {
char *buf = (char *)alloca (40 + strlen (called_thing)); cp_error_at ("too many arguments to %s `%+D'", called_thing,
sprintf (buf, "too many arguments to %s `%%s'", called_thing); fndecl);
error_with_decl (fndecl, buf);
error ("at this point in file"); error ("at this point in file");
} }
else else
...@@ -4877,30 +4905,42 @@ build_conditional_expr (ifexp, op1, op2) ...@@ -4877,30 +4905,42 @@ build_conditional_expr (ifexp, op1, op2)
cp_error ("aggregate mismatch in conditional expression: `%T' vs `%T'", type1, type2); cp_error ("aggregate mismatch in conditional expression: `%T' vs `%T'", type1, type2);
return error_mark_node; 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)) 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) 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; return error_mark_node;
} }
if (tmp == error_mark_node) if (tmp == error_mark_node)
error ("ambiguous pointer conversion"); error ("ambiguous pointer conversion");
result_type = type2; else
STRIP_NOPS (tmp);
result_type = common_type (type1, TREE_TYPE (tmp));
op1 = tmp; op1 = tmp;
} }
else if (code2 == RECORD_TYPE && TYPE_HAS_CONVERSION (type2)) 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) 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; return error_mark_node;
} }
if (tmp == error_mark_node) if (tmp == error_mark_node)
error ("ambiguous pointer conversion"); error ("ambiguous pointer conversion");
result_type = type1; else
STRIP_NOPS (tmp);
result_type = common_type (type1, TREE_TYPE (tmp));
op2 = tmp; op2 = tmp;
} }
else if (flag_cond_mismatch) else if (flag_cond_mismatch)
...@@ -5183,12 +5223,6 @@ build_c_cast (type, expr, allow_nonconverting) ...@@ -5183,12 +5223,6 @@ build_c_cast (type, expr, allow_nonconverting)
return error_mark_node; 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) if (current_template_parms)
{ {
tree t = build_min (CAST_EXPR, type, tree t = build_min (CAST_EXPR, type,
...@@ -5471,9 +5505,9 @@ build_modify_expr (lhs, modifycode, rhs) ...@@ -5471,9 +5505,9 @@ build_modify_expr (lhs, modifycode, rhs)
/* Do the default thing */; /* Do the default thing */;
else else
{ {
result = build_method_call (lhs, constructor_name_full (lhstype), result = build_method_call (lhs, ctor_identifier,
build_tree_list (NULL_TREE, rhs), build_tree_list (NULL_TREE, rhs),
NULL_TREE, LOOKUP_NORMAL); TYPE_BINFO (lhstype), LOOKUP_NORMAL);
if (result == NULL_TREE) if (result == NULL_TREE)
return error_mark_node; return error_mark_node;
return result; return result;
...@@ -6688,7 +6722,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) ...@@ -6688,7 +6722,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
{ {
if (TYPE_HAS_INIT_REF (type)) 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), build_tree_list (NULL_TREE, rhs),
TYPE_BINFO (type), LOOKUP_NORMAL); TYPE_BINFO (type), LOOKUP_NORMAL);
...@@ -6721,7 +6755,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) ...@@ -6721,7 +6755,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
return rhs; 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)) if (type == TREE_TYPE (rhs))
......
...@@ -71,29 +71,6 @@ binfo_or_else (parent_or_type, type) ...@@ -71,29 +71,6 @@ binfo_or_else (parent_or_type, type)
return NULL_TREE; 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 /* 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, 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 rather than just pedwarns. If `SOFT' is 1, then we just pedwarn. (For
...@@ -108,40 +85,37 @@ readonly_error (arg, string, soft) ...@@ -108,40 +85,37 @@ readonly_error (arg, string, soft)
void (*fn)(); void (*fn)();
if (soft) if (soft)
fn = pedwarn; fn = cp_pedwarn;
else else
fn = error; fn = cp_error;
if (TREE_CODE (arg) == COMPONENT_REF) if (TREE_CODE (arg) == COMPONENT_REF)
{ {
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0)))) 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 else
fmt = "%s of read-only member `%s'"; fmt = "%s of read-only member `%D'";
(*fn) (fmt, string, lang_printable_name (TREE_OPERAND (arg, 1))); (*fn) (fmt, string, TREE_OPERAND (arg, 1));
} }
else if (TREE_CODE (arg) == VAR_DECL) else if (TREE_CODE (arg) == VAR_DECL)
{ {
if (DECL_LANG_SPECIFIC (arg) if (DECL_LANG_SPECIFIC (arg)
&& DECL_IN_AGGR_P (arg) && DECL_IN_AGGR_P (arg)
&& !TREE_STATIC (arg)) && !TREE_STATIC (arg))
fmt = "%s of constant field `%s'"; fmt = "%s of constant field `%D'";
else else
fmt = "%s of read-only variable `%s'"; fmt = "%s of read-only variable `%D'";
(*fn) (fmt, string, lang_printable_name (arg)); (*fn) (fmt, string, arg);
} }
else if (TREE_CODE (arg) == PARM_DECL) else if (TREE_CODE (arg) == PARM_DECL)
(*fn) ("%s of read-only parameter `%s'", string, (*fn) ("%s of read-only parameter `%D'", string, arg);
lang_printable_name (arg));
else if (TREE_CODE (arg) == INDIRECT_REF else if (TREE_CODE (arg) == INDIRECT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))) == REFERENCE_TYPE && TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))) == REFERENCE_TYPE
&& (TREE_CODE (TREE_OPERAND (arg, 0)) == VAR_DECL && (TREE_CODE (TREE_OPERAND (arg, 0)) == VAR_DECL
|| TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL)) || TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL))
(*fn) ("%s of read-only reference `%s'", (*fn) ("%s of read-only reference `%D'", string, TREE_OPERAND (arg, 0));
string, lang_printable_name (TREE_OPERAND (arg, 0)));
else if (TREE_CODE (arg) == RESULT_DECL) else if (TREE_CODE (arg) == RESULT_DECL)
(*fn) ("%s of read-only named return value `%s'", (*fn) ("%s of read-only named return value `%D'", string, arg);
string, lang_printable_name (arg));
else else
(*fn) ("%s of read-only location", string); (*fn) ("%s of read-only location", string);
} }
...@@ -239,8 +213,7 @@ incomplete_type_error (value, type) ...@@ -239,8 +213,7 @@ incomplete_type_error (value, type)
if (value != 0 && (TREE_CODE (value) == VAR_DECL if (value != 0 && (TREE_CODE (value) == VAR_DECL
|| TREE_CODE (value) == PARM_DECL)) || TREE_CODE (value) == PARM_DECL))
error ("`%s' has an incomplete type", cp_error ("`%D' has incomplete type", value);
IDENTIFIER_POINTER (DECL_NAME (value)));
else else
{ {
retry: retry:
...@@ -249,15 +222,9 @@ incomplete_type_error (value, type) ...@@ -249,15 +222,9 @@ incomplete_type_error (value, type)
switch (TREE_CODE (type)) switch (TREE_CODE (type))
{ {
case RECORD_TYPE: case RECORD_TYPE:
errmsg = "invalid use of undefined type `struct %s'";
break;
case UNION_TYPE: case UNION_TYPE:
errmsg = "invalid use of undefined type `union %s'";
break;
case ENUMERAL_TYPE: case ENUMERAL_TYPE:
errmsg = "invalid use of undefined type `enum %s'"; errmsg = "invalid use of undefined type `%#T'";
break; break;
case VOID_TYPE: case VOID_TYPE:
...@@ -281,7 +248,7 @@ incomplete_type_error (value, type) ...@@ -281,7 +248,7 @@ incomplete_type_error (value, type)
my_friendly_abort (108); my_friendly_abort (108);
} }
error_with_aggr_type (type, errmsg); cp_error (errmsg, type);
} }
} }
...@@ -1410,28 +1377,23 @@ build_m_component_ref (datum, component) ...@@ -1410,28 +1377,23 @@ build_m_component_ref (datum, component)
return build (OFFSET_REF, rettype, datum, component); return build (OFFSET_REF, rettype, datum, component);
} }
/* Return a tree node for the expression TYPENAME '(' PARMS ')'. /* 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. */
tree tree
build_functional_cast (exp, parms) build_functional_cast (exp, parms)
tree exp; tree exp;
tree parms; tree parms;
{ {
tree binfo;
/* This is either a call to a constructor, /* This is either a call to a constructor,
or a C cast in C++'s `functional' notation. */ or a C cast in C++'s `functional' notation. */
tree type, name = NULL_TREE; tree type;
tree expr_as_ctor = NULL_TREE;
if (exp == error_mark_node || parms == error_mark_node) if (exp == error_mark_node || parms == error_mark_node)
return error_mark_node; return error_mark_node;
if (TREE_CODE (exp) == IDENTIFIER_NODE) if (TREE_CODE (exp) == IDENTIFIER_NODE)
{ {
name = exp;
if (IDENTIFIER_HAS_TYPE_VALUE (exp)) if (IDENTIFIER_HAS_TYPE_VALUE (exp))
/* Either an enum or an aggregate type. */ /* Either an enum or an aggregate type. */
type = IDENTIFIER_TYPE_VALUE (exp); type = IDENTIFIER_TYPE_VALUE (exp);
...@@ -1440,7 +1402,7 @@ build_functional_cast (exp, parms) ...@@ -1440,7 +1402,7 @@ build_functional_cast (exp, parms)
type = lookup_name (exp, 1); type = lookup_name (exp, 1);
if (!type || TREE_CODE (type) != TYPE_DECL) 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; return error_mark_node;
} }
type = TREE_TYPE (type); type = TREE_TYPE (type);
...@@ -1482,13 +1444,6 @@ build_functional_cast (exp, parms) ...@@ -1482,13 +1444,6 @@ build_functional_cast (exp, parms)
then the slot being initialized will be filled in. */ 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) if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
{ {
cp_error ("type `%T' is not yet defined", type); cp_error ("type `%T' is not yet defined", type);
...@@ -1496,15 +1451,15 @@ build_functional_cast (exp, parms) ...@@ -1496,15 +1451,15 @@ build_functional_cast (exp, parms)
} }
if (parms && TREE_CHAIN (parms) == NULL_TREE) 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, exp = build_method_call (NULL_TREE, ctor_identifier, parms,
NULL_TREE, LOOKUP_NORMAL); TYPE_BINFO (type), LOOKUP_NORMAL);
if (expr_as_ctor == error_mark_node) if (exp == error_mark_node)
return 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 /* 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