Commit 7177d104 by Mike Stump

33rd Cygnus<->FSF merge

From-SVN: r7134
parent 0207efa2
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -3810,7 +3810,8 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -3810,7 +3810,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (need_vtbl == needed) if (need_vtbl == needed)
{ {
function = build_vfn_ref (&TREE_VALUE (parms), instance, DECL_VINDEX (function)); function = build_vfn_ref (&TREE_VALUE (parms), instance,
DECL_VINDEX (function));
TREE_TYPE (function) = build_pointer_type (fntype); TREE_TYPE (function) = build_pointer_type (fntype);
} }
...@@ -3975,7 +3976,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx) ...@@ -3975,7 +3976,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
return error_mark_node; return error_mark_node;
} }
if (! TREE_OVERLOADED (fnname)) if (TREE_CODE (functions) == FUNCTION_DECL)
{ {
functions = DECL_MAIN_VARIANT (functions); functions = DECL_MAIN_VARIANT (functions);
if (final_cp) if (final_cp)
......
...@@ -1071,11 +1071,11 @@ struct lang_decl ...@@ -1071,11 +1071,11 @@ struct lang_decl
or virtual baseclasses. */ or virtual baseclasses. */
#define TYPE_USES_COMPLEX_INHERITANCE(NODE) (TREE_LANG_FLAG_1 (NODE)) #define TYPE_USES_COMPLEX_INHERITANCE(NODE) (TREE_LANG_FLAG_1 (NODE))
#if 0 /* UNUSED */
/* Nonzero in IDENTIFIER_NODE means that this name is overloaded, and /* Nonzero in IDENTIFIER_NODE means that this name is overloaded, and
should be looked up in a non-standard way. */ should be looked up in a non-standard way. */
#define TREE_OVERLOADED(NODE) (TREE_LANG_FLAG_0 (NODE)) #define TREE_OVERLOADED(NODE) (TREE_LANG_FLAG_0 (NODE))
#if 0 /* UNUSED */ #define DECL_OVERLOADED(NODE) (NOTHING)
#define DECL_OVERLOADED(NODE) (DECL_LANG_FLAG_4 (NODE))
#endif #endif
/* Nonzero if this (non-TYPE)_DECL has its virtual attribute set. /* Nonzero if this (non-TYPE)_DECL has its virtual attribute set.
...@@ -1251,7 +1251,13 @@ struct lang_decl ...@@ -1251,7 +1251,13 @@ struct lang_decl
#define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT(NODE) #define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT(NODE)
#define DECL_TEMPLATE_INSTANTIATIONS(NODE) DECL_VINDEX(NODE) #define DECL_TEMPLATE_INSTANTIATIONS(NODE) DECL_VINDEX(NODE)
#define THUNK_DELTA(DECL) ((DECL)->decl.frame_size) /* Macros for a DECL or TYPE generated from a template to indicate that it
was explicitly instantiated. */
#define DECL_EXPLICITLY_INSTANTIATED(NODE) (DECL_LANG_FLAG_4 (NODE))
#define CLASSTYPE_EXPLICITLY_INSTANTIATED(NODE) \
(DECL_EXPLICITLY_INSTANTIATED (TYPE_NAME (NODE)))
#define THUNK_DELTA(DECL) ((DECL)->decl.frame_size.u)
/* ...and for unexpanded-parameterized-type nodes. */ /* ...and for unexpanded-parameterized-type nodes. */
#define UPT_TEMPLATE(NODE) TREE_PURPOSE(TYPE_VALUES(NODE)) #define UPT_TEMPLATE(NODE) TREE_PURPOSE(TYPE_VALUES(NODE))
...@@ -1334,14 +1340,6 @@ extern tree class_type_node, record_type_node, union_type_node, enum_type_node; ...@@ -1334,14 +1340,6 @@ extern tree class_type_node, record_type_node, union_type_node, enum_type_node;
extern tree exception_type_node, unknown_type_node; extern tree exception_type_node, unknown_type_node;
extern tree opaque_type_node, signature_type_node; extern tree opaque_type_node, signature_type_node;
/* The largest size a virtual function table can be.
Must be a (power of 2). */
#ifndef VINDEX_MAX
#define VINDEX_MAX ((unsigned)128)
/* This is the integer ~ (vindex_max - 1). */
#endif
extern tree vtbl_mask;
/* Array type `(void *)[]' */ /* Array type `(void *)[]' */
extern tree vtbl_type_node; extern tree vtbl_type_node;
extern tree delta_type_node; extern tree delta_type_node;
...@@ -1952,7 +1950,7 @@ extern tree build_dynamic_cast PROTO((tree, tree)); ...@@ -1952,7 +1950,7 @@ extern tree build_dynamic_cast PROTO((tree, tree));
/* in init.c */ /* in init.c */
extern void emit_base_init PROTO((tree, int)); extern void emit_base_init PROTO((tree, int));
extern void check_base_init PROTO((tree)); extern void check_base_init PROTO((tree));
extern void init_vtbl_ptrs PROTO((tree, int, int)); extern void expand_direct_vtbls_init PROTO((tree, tree, int, int, tree));
extern void do_member_init PROTO((tree, tree, tree)); extern void do_member_init PROTO((tree, tree, tree));
extern void expand_member_init PROTO((tree, tree, tree)); extern void expand_member_init PROTO((tree, tree, tree));
extern void expand_aggr_init PROTO((tree, tree, int)); extern void expand_aggr_init PROTO((tree, tree, int));
...@@ -2101,12 +2099,12 @@ extern tree lookup_nested_tag PROTO((tree, tree)); ...@@ -2101,12 +2099,12 @@ extern tree lookup_nested_tag PROTO((tree, tree));
extern HOST_WIDE_INT breadth_first_search PROTO((tree, int (*)(), int (*)())); extern HOST_WIDE_INT breadth_first_search PROTO((tree, int (*)(), int (*)()));
extern int tree_needs_constructor_p PROTO((tree, int)); extern int tree_needs_constructor_p PROTO((tree, int));
extern int tree_has_any_destructor_p PROTO((tree, int)); extern int tree_has_any_destructor_p PROTO((tree, int));
extern tree get_first_matching_virtual PROTO((tree, tree, int)); extern tree get_matching_virtual PROTO((tree, tree, int));
extern tree get_abstract_virtuals PROTO((tree)); extern tree get_abstract_virtuals PROTO((tree));
extern tree get_baselinks PROTO((tree, tree, tree)); extern tree get_baselinks PROTO((tree, tree, tree));
extern tree next_baselink PROTO((tree)); extern tree next_baselink PROTO((tree));
extern tree init_vbase_pointers PROTO((tree, tree)); extern tree init_vbase_pointers PROTO((tree, tree));
extern void expand_vbase_vtables_init PROTO((tree, tree, tree, tree, int)); extern void expand_indirect_vtbls_init PROTO((tree, tree, tree, int));
extern void clear_search_slots PROTO((tree)); extern void clear_search_slots PROTO((tree));
extern tree get_vbase_types PROTO((tree)); extern tree get_vbase_types PROTO((tree));
extern void build_mi_matrix PROTO((tree)); extern void build_mi_matrix PROTO((tree));
......
...@@ -706,10 +706,11 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum, ...@@ -706,10 +706,11 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
else if (form == REFERENCE_TYPE) else if (form == REFERENCE_TYPE)
{ {
rval = copy_node (expr); rval = build1 (NOP_EXPR,
TREE_TYPE (rval) = build_pointer_type (TREE_TYPE (TREE_TYPE (expr))); build_pointer_type (TREE_TYPE (TREE_TYPE (expr))),
expr);
rval = convert (build_pointer_type (TREE_TYPE (reftype)), rval); rval = convert (build_pointer_type (TREE_TYPE (reftype)), rval);
TREE_TYPE (rval) = reftype; rval = build1 (NOP_EXPR, reftype, rval);
return rval; return rval;
} }
...@@ -734,7 +735,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum, ...@@ -734,7 +735,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
if (rval != error_mark_node) if (rval != error_mark_node)
rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), rval); rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), rval);
if (rval != error_mark_node) if (rval != error_mark_node)
TREE_TYPE (rval) = reftype; rval = build1 (NOP_EXPR, reftype, rval);
} }
else if (decl == error_mark_node || decl == NULL_TREE) else if (decl == error_mark_node || decl == NULL_TREE)
{ {
...@@ -1146,9 +1147,8 @@ convert_pointer_to_real (binfo, expr) ...@@ -1146,9 +1147,8 @@ convert_pointer_to_real (binfo, expr)
but if it is, give them an error message that they can read. */ but if it is, give them an error message that they can read. */
if (distance < 0) if (distance < 0)
{ {
cp_error ("cannot convert a pointer of type `%T'", cp_error ("cannot convert a pointer of type `%T' to a pointer of type `%T'",
TREE_TYPE (intype)); TREE_TYPE (intype), type);
cp_error ("to a pointer of type `%T'", type);
if (distance == -2) if (distance == -2)
cp_error ("because `%T' is an ambiguous base class", type); cp_error ("because `%T' is an ambiguous base class", type);
......
...@@ -1381,6 +1381,10 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree) ...@@ -1381,6 +1381,10 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree)
if (DECL_FRIEND_P (value)) if (DECL_FRIEND_P (value))
return void_type_node; return void_type_node;
if (current_function_decl)
cp_error ("method `%#D' of local class must be defined in class body",
value);
DECL_IN_AGGR_P (value) = 1; DECL_IN_AGGR_P (value) = 1;
return value; return value;
} }
...@@ -2307,6 +2311,37 @@ mark_vtable_entries (decl) ...@@ -2307,6 +2311,37 @@ mark_vtable_entries (decl)
tree fnaddr = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries)); tree fnaddr = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries));
tree fn = TREE_OPERAND (fnaddr, 0); tree fn = TREE_OPERAND (fnaddr, 0);
TREE_ADDRESSABLE (fn) = 1; TREE_ADDRESSABLE (fn) = 1;
if (DECL_ABSTRACT_VIRTUAL_P (fn))
{
extern tree abort_fndecl;
TREE_OPERAND (fnaddr, 0) = abort_fndecl;
}
}
}
/* Set TREE_PUBLIC and/or TREE_EXTERN on the vtable DECL,
based on TYPE and other static flags.
Note that anything public is tagged TREE_PUBLIC, whether
it's public in this file or in another one. */
static void
import_export_vtable (decl, type)
tree decl, type;
{
if (write_virtuals >= 2)
{
if (CLASSTYPE_INTERFACE_KNOWN (type))
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type);
}
}
else if (write_virtuals != 0)
{
TREE_PUBLIC (decl) = 1;
if (write_virtuals < 0)
DECL_EXTERNAL (decl) = 1;
} }
} }
...@@ -2315,6 +2350,8 @@ finish_vtable_vardecl (prev, vars) ...@@ -2315,6 +2350,8 @@ finish_vtable_vardecl (prev, vars)
tree prev, vars; tree prev, vars;
{ {
tree ctype = DECL_CONTEXT (vars); tree ctype = DECL_CONTEXT (vars);
import_export_vtable (vars, ctype);
if (flag_vtable_thunks && !CLASSTYPE_INTERFACE_KNOWN (ctype)) if (flag_vtable_thunks && !CLASSTYPE_INTERFACE_KNOWN (ctype))
{ {
tree method; tree method;
...@@ -2578,6 +2615,10 @@ finish_file () ...@@ -2578,6 +2615,10 @@ finish_file ()
lineno = DECL_SOURCE_LINE (decl); lineno = DECL_SOURCE_LINE (decl);
emit_note (input_filename, lineno); emit_note (input_filename, lineno);
/* 9.5p5: The initializer of a static member of a class has
the same acess rights as a member function. */
DECL_CLASS_CONTEXT (current_function_decl) = DECL_CONTEXT (decl);
if (init) if (init)
{ {
if (TREE_CODE (init) == VAR_DECL) if (TREE_CODE (init) == VAR_DECL)
...@@ -2615,19 +2656,7 @@ finish_file () ...@@ -2615,19 +2656,7 @@ finish_file ()
if (IS_AGGR_TYPE (TREE_TYPE (decl)) if (IS_AGGR_TYPE (TREE_TYPE (decl))
|| init == 0 || init == 0
|| TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
{ expand_aggr_init (decl, init, 0);
#if 0
/* Set this up so is_friend() works properly on _GLOBAL_
fns. */
tree old_dcc = DECL_CLASS_CONTEXT (current_function_decl);
if (old_dcc == NULL_TREE && IS_AGGR_TYPE (TREE_TYPE (decl)))
DECL_CLASS_CONTEXT (current_function_decl) = TREE_TYPE (decl);
expand_aggr_init (decl, init, 0);
DECL_CLASS_CONTEXT (current_function_decl) = old_dcc;
#else
expand_aggr_init (decl, init, 0);
#endif
}
else if (TREE_CODE (init) == TREE_VEC) else if (TREE_CODE (init) == TREE_VEC)
{ {
expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0), expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0),
...@@ -2638,6 +2667,8 @@ finish_file () ...@@ -2638,6 +2667,8 @@ finish_file ()
} }
else else
expand_assignment (decl, init, 0, 0); expand_assignment (decl, init, 0, 0);
DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE;
} }
else if (TREE_CODE (decl) == SAVE_EXPR) else if (TREE_CODE (decl) == SAVE_EXPR)
{ {
......
...@@ -186,8 +186,7 @@ dump_type (t, v) ...@@ -186,8 +186,7 @@ dump_type (t, v)
break; break;
case TYPE_DECL: case TYPE_DECL:
dump_readonly_or_volatile (t, after); dump_decl (t, v);
OB_PUTID (DECL_NAME (t));
break; break;
case INTEGER_TYPE: case INTEGER_TYPE:
...@@ -553,6 +552,17 @@ dump_decl (t, v) ...@@ -553,6 +552,17 @@ dump_decl (t, v)
OB_PUTS (" /* decl error */ "); OB_PUTS (" /* decl error */ ");
break; break;
case TYPE_DECL:
if (TYPE_NAME (TREE_TYPE (t)) != t)
{
if (v > 0)
OB_PUTS ("typedef ");
goto general;
}
dump_type (TREE_TYPE (t), v);
break;
case VAR_DECL: case VAR_DECL:
if (VTABLE_NAME_P (DECL_NAME (t))) if (VTABLE_NAME_P (DECL_NAME (t)))
{ {
...@@ -563,10 +573,11 @@ dump_decl (t, v) ...@@ -563,10 +573,11 @@ dump_decl (t, v)
/* else fall through */ /* else fall through */
case FIELD_DECL: case FIELD_DECL:
case PARM_DECL: case PARM_DECL:
general:
if (v > 0) if (v > 0)
{ {
dump_type_prefix (TREE_TYPE (t), v); dump_type_prefix (TREE_TYPE (t), v);
OB_PUTC(' '); OB_PUTC (' ');
} }
/* DECL_CLASS_CONTEXT isn't being set in some cases. Hmm... */ /* DECL_CLASS_CONTEXT isn't being set in some cases. Hmm... */
if (TREE_CODE (t) == FIELD_DECL if (TREE_CODE (t) == FIELD_DECL
...@@ -574,13 +585,14 @@ dump_decl (t, v) ...@@ -574,13 +585,14 @@ dump_decl (t, v)
&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't')) && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't'))
{ {
dump_type (DECL_CONTEXT (t), 0); dump_type (DECL_CONTEXT (t), 0);
OB_PUTC2(':', ':'); OB_PUTC2 (':', ':');
} }
if (DECL_NAME (t)) if (DECL_NAME (t))
dump_decl (DECL_NAME (t), v); dump_decl (DECL_NAME (t), v);
else else
OB_PUTS ("{anon}"); OB_PUTS ("{anon}");
if (v > 0) dump_type_suffix (TREE_TYPE (t), v); if (v > 0)
dump_type_suffix (TREE_TYPE (t), v);
break; break;
case ARRAY_REF: case ARRAY_REF:
...@@ -598,10 +610,6 @@ dump_decl (t, v) ...@@ -598,10 +610,6 @@ dump_decl (t, v)
dump_type (t, v); dump_type (t, v);
break; break;
case TYPE_DECL:
dump_type (TREE_TYPE (t), v);
break;
case TYPE_EXPR: case TYPE_EXPR:
my_friendly_abort (69); my_friendly_abort (69);
break; break;
......
...@@ -1162,11 +1162,13 @@ do_pending_inlines () ...@@ -1162,11 +1162,13 @@ do_pending_inlines ()
/* Pass back a handle on the rest of the inline functions, so that they /* Pass back a handle on the rest of the inline functions, so that they
can be processed later. */ can be processed later. */
yylval.ttype = build_tree_list ((tree) t, t->fndecl); yylval.ttype = build_tree_list ((tree) t, t->fndecl);
#if 0
if (flag_default_inline && t->fndecl if (flag_default_inline && t->fndecl
/* If we're working from a template, don't change /* If we're working from a template, don't change
the `inline' state. */ the `inline' state. */
&& t->parm_vec == NULL_TREE) && t->parm_vec == NULL_TREE)
DECL_INLINE (t->fndecl) = 1; DECL_INLINE (t->fndecl) = 1;
#endif
DECL_PENDING_INLINE_INFO (t->fndecl) = 0; DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
} }
...@@ -1215,11 +1217,13 @@ process_next_inline (t) ...@@ -1215,11 +1217,13 @@ process_next_inline (t)
input_filename = i->filename; input_filename = i->filename;
yychar = PRE_PARSED_FUNCTION_DECL; yychar = PRE_PARSED_FUNCTION_DECL;
yylval.ttype = build_tree_list ((tree) i, i->fndecl); yylval.ttype = build_tree_list ((tree) i, i->fndecl);
#if 0
if (flag_default_inline if (flag_default_inline
/* If we're working from a template, don't change /* If we're working from a template, don't change
the `inline' state. */ the `inline' state. */
&& i->parm_vec == NULL_TREE) && i->parm_vec == NULL_TREE)
DECL_INLINE (i->fndecl) = 1; DECL_INLINE (i->fndecl) = 1;
#endif
DECL_PENDING_INLINE_INFO (i->fndecl) = 0; DECL_PENDING_INLINE_INFO (i->fndecl) = 0;
} }
if (i) if (i)
...@@ -2577,7 +2581,7 @@ check_newline () ...@@ -2577,7 +2581,7 @@ check_newline ()
else else
error ("`#pragma implementation' can only appear at top-level"); error ("`#pragma implementation' can only appear at top-level");
interface_only = 0; interface_only = 0;
#if 0 #if 1
/* We make this non-zero so that we infer decl linkage /* We make this non-zero so that we infer decl linkage
in the impl file only for variables first declared in the impl file only for variables first declared
in the interface file. */ in the interface file. */
...@@ -4576,6 +4580,7 @@ build_lang_decl (code, name, type) ...@@ -4576,6 +4580,7 @@ build_lang_decl (code, name, type)
if (current_lang_name == lang_name_cplusplus) if (current_lang_name == lang_name_cplusplus)
{ {
DECL_LANGUAGE (t) = lang_cplusplus; DECL_LANGUAGE (t) = lang_cplusplus;
#if 0
#ifndef NO_AUTO_OVERLOAD #ifndef NO_AUTO_OVERLOAD
if (code == FUNCTION_DECL && name != 0 if (code == FUNCTION_DECL && name != 0
&& ! (IDENTIFIER_LENGTH (name) == 4 && ! (IDENTIFIER_LENGTH (name) == 4
...@@ -4587,6 +4592,7 @@ build_lang_decl (code, name, type) ...@@ -4587,6 +4592,7 @@ build_lang_decl (code, name, type)
&& strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0)) && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0))
TREE_OVERLOADED (name) = 1; TREE_OVERLOADED (name) = 1;
#endif #endif
#endif
} }
else if (current_lang_name == lang_name_c) else if (current_lang_name == lang_name_c)
DECL_LANGUAGE (t) = lang_c; DECL_LANGUAGE (t) = lang_c;
......
...@@ -111,8 +111,10 @@ do_inline_function_hair (type, friend_list) ...@@ -111,8 +111,10 @@ do_inline_function_hair (type, friend_list)
args = TREE_CHAIN (args); args = TREE_CHAIN (args);
} }
/* Allow this decl to be seen in global scope */ /* Allow this decl to be seen in global scope. Don't do this for
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method; local class methods, though. */
if (! current_function_decl)
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method;
} }
method = TREE_CHAIN (method); method = TREE_CHAIN (method);
} }
...@@ -1698,6 +1700,7 @@ emit_thunk (thunk_fndecl) ...@@ -1698,6 +1700,7 @@ emit_thunk (thunk_fndecl)
int delta = THUNK_DELTA (thunk_fndecl); int delta = THUNK_DELTA (thunk_fndecl);
int tem; int tem;
int failure = 0; int failure = 0;
extern int current_call_is_indirect; /* Needed for (at least) HPPA. */
/* Used to remember which regs we need to emit a USE rtx for. */ /* Used to remember which regs we need to emit a USE rtx for. */
rtx need_use[FIRST_PSEUDO_REGISTER]; rtx need_use[FIRST_PSEUDO_REGISTER];
......
...@@ -779,8 +779,9 @@ identifier_defn: ...@@ -779,8 +779,9 @@ identifier_defn:
explicit_instantiation: explicit_instantiation:
TEMPLATE aggr template_type TEMPLATE aggr template_type
{ do_type_instantiation ($3); }
| TEMPLATE typed_declspecs declarator | TEMPLATE typed_declspecs declarator
{ do_function_instantiation ($2, $3); } { do_function_instantiation ($2, $3); }
; ;
template_type: template_type:
...@@ -844,6 +845,8 @@ template_instantiate_once: ...@@ -844,6 +845,8 @@ template_instantiate_once:
pop_obstacks (); pop_obstacks ();
pushdecl_top_level (decl); pushdecl_top_level (decl);
} }
/* Kludge; see instantiate_class_template. */
TYPE_BEING_DEFINED (t) = 0;
} }
left_curly opt.component_decl_list '}' left_curly opt.component_decl_list '}'
{ {
......
...@@ -1013,6 +1013,8 @@ instantiate_class_template (classname, setup_parse) ...@@ -1013,6 +1013,8 @@ instantiate_class_template (classname, setup_parse)
/* Get interface/implementation back in sync. */ /* Get interface/implementation back in sync. */
extract_interface_info (); extract_interface_info ();
overload_template_name (classname, 0); overload_template_name (classname, 0);
/* Kludge so that we don't get screwed by our own base classes. */
TYPE_BEING_DEFINED (TREE_TYPE (classname)) = 1;
yychar = PRE_PARSED_CLASS_DECL; yychar = PRE_PARSED_CLASS_DECL;
yylval.ttype = classname; yylval.ttype = classname;
processing_template_defn++; processing_template_defn++;
...@@ -2187,6 +2189,10 @@ do_pending_expansions () ...@@ -2187,6 +2189,10 @@ do_pending_expansions ()
|| TREE_CODE (t) == VAR_DECL, 294); || TREE_CODE (t) == VAR_DECL, 294);
if (TREE_ASM_WRITTEN (t)) if (TREE_ASM_WRITTEN (t))
DECIDE (0); DECIDE (0);
if (DECL_EXPLICITLY_INSTANTIATED (t))
DECIDE (1);
/* If it's a method, let the class type decide it. /* If it's a method, let the class type decide it.
@@ What if the method template is in a separate file? @@ What if the method template is in a separate file?
Maybe both file contexts should be taken into account? Maybe both file contexts should be taken into account?
...@@ -2311,8 +2317,29 @@ do_function_instantiation (declspecs, declarator) ...@@ -2311,8 +2317,29 @@ do_function_instantiation (declspecs, declarator)
} }
} }
} }
if (!result) if (! result)
cp_error ("no matching template for `%D' found", decl); cp_error ("no matching template for `%D' found", decl);
DECL_EXPLICITLY_INSTANTIATED (result) = 1;
}
void
do_type_instantiation (name)
tree name;
{
tree t = TREE_TYPE (name);
CLASSTYPE_EXPLICITLY_INSTANTIATED (t) = 1;
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 1;
/* this should really be done by instantiate_member_templates */
{
tree method = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
for (; method; method = TREE_CHAIN (method))
DECL_EXPLICITLY_INSTANTIATED (method) = 1;
}
/* and data member templates, too */
} }
tree tree
......
...@@ -687,6 +687,22 @@ lookup_field_1 (type, name) ...@@ -687,6 +687,22 @@ lookup_field_1 (type, name)
return NULL_TREE; return NULL_TREE;
} }
/* There are a number of cases we need to be aware of here:
current_class_type current_function_decl
* global NULL NULL
* fn-local NULL SET
* class-local SET NULL
* class->fn SET SET
* fn->class SET SET
Those last two make life interesting. If we're in a function which is
itself inside a class, we need decls to go into the fn's decls (our
second case below). But if we're in a class and the class itself is
inside a function, we need decls to go into the decls for the class. To
achieve this last goal, we must see if, when both current_class_decl and
current_function_decl are set, the class was declared inside that
function. If so, we know to put the decls into the class's scope. */
tree tree
current_scope () current_scope ()
{ {
...@@ -1842,14 +1858,14 @@ int tree_has_any_destructor_p (binfo, i) ...@@ -1842,14 +1858,14 @@ int tree_has_any_destructor_p (binfo, i)
return TYPE_NEEDS_DESTRUCTOR (type); return TYPE_NEEDS_DESTRUCTOR (type);
} }
/* Given a class type TYPE, and a function decl FNDECL, /* Given a class type TYPE, and a function decl FNDECL, look for a
look for the first function the TYPE's hierarchy which virtual function in TYPE's hierarchy which FNDECL could match as a
FNDECL could match as a virtual function. virtual function. It doesn't matter which one we find.
DTORP is nonzero if we are looking for a destructor. Destructors DTORP is nonzero if we are looking for a destructor. Destructors
need special treatment because they do not match by name. */ need special treatment because they do not match by name. */
tree tree
get_first_matching_virtual (binfo, fndecl, dtorp) get_matching_virtual (binfo, fndecl, dtorp)
tree binfo, fndecl; tree binfo, fndecl;
int dtorp; int dtorp;
{ {
...@@ -1863,22 +1879,11 @@ get_first_matching_virtual (binfo, fndecl, dtorp) ...@@ -1863,22 +1879,11 @@ get_first_matching_virtual (binfo, fndecl, dtorp)
tmp = get_virtual_destructor (binfo, -1); tmp = get_virtual_destructor (binfo, -1);
if (tmp) if (tmp)
{ return tmp;
if (get_base_distance (DECL_CONTEXT (tmp),
DECL_CONTEXT (fndecl), 0, 0) > 0)
DECL_CONTEXT (fndecl) = DECL_CONTEXT (tmp);
return tmp;
}
tmp = (tree) breadth_first_search (binfo, tmp = (tree) breadth_first_search (binfo,
(pfi) get_virtual_destructor, (pfi) get_virtual_destructor,
tree_has_any_destructor_p); tree_has_any_destructor_p);
if (tmp)
{
if (get_base_distance (DECL_CONTEXT (tmp),
DECL_CONTEXT (fndecl), 0, 0) > 0)
DECL_CONTEXT (fndecl) = DECL_CONTEXT (tmp);
}
return tmp; return tmp;
} }
else else
...@@ -1931,33 +1936,20 @@ get_first_matching_virtual (binfo, fndecl, dtorp) ...@@ -1931,33 +1936,20 @@ get_first_matching_virtual (binfo, fndecl, dtorp)
} }
if (tmp) if (tmp)
{ {
/* If this is ambiguous, we will warn about it later. */ best = tmp;
if (best) break;
{
if (get_base_distance (DECL_CLASS_CONTEXT (best),
DECL_CLASS_CONTEXT (tmp), 0, 0) > 0)
best = tmp;
}
else
best = tmp;
} }
} }
if (best == NULL_TREE && warn_overloaded_virtual) if (best == NULL_TREE && warn_overloaded_virtual)
cp_warning_at ("conflicting specification deriving virtual function `%D'", fndecl); cp_warning_at ("conflicting specification deriving virtual function `%D'", fndecl);
if (best)
{
if (get_base_distance (DECL_CONTEXT (best),
DECL_CONTEXT (fndecl), 0, 0) > 0)
DECL_CONTEXT (fndecl) = DECL_CONTEXT (best);
}
return best; return best;
} }
} }
/* Return the list of virtual functions which are abstract in type TYPE /* Return the list of virtual functions which are abstract in type
that come from non virtual base classes. See init_vtbl_ptrs for TYPE that come from non virtual base classes. See
the style of search we do. */ expand_direct_vtbls_init for the style of search we do. */
static tree static tree
get_abstract_virtuals_1 (binfo, do_self, abstract_virtuals) get_abstract_virtuals_1 (binfo, do_self, abstract_virtuals)
tree binfo, abstract_virtuals; tree binfo, abstract_virtuals;
...@@ -2364,7 +2356,9 @@ dfs_debug_mark (binfo) ...@@ -2364,7 +2356,9 @@ dfs_debug_mark (binfo)
} }
/* Attach to the type of the virtual base class, the pointer to the /* Attach to the type of the virtual base class, the pointer to the
virtual base class, given the global pointer vbase_decl_ptr. */ virtual base class, given the global pointer vbase_decl_ptr.
We use the global vbase_types. ICK! */
static void static void
dfs_find_vbases (binfo) dfs_find_vbases (binfo)
tree binfo; tree binfo;
...@@ -2471,32 +2465,32 @@ init_vbase_pointers (type, decl_ptr) ...@@ -2471,32 +2465,32 @@ init_vbase_pointers (type, decl_ptr)
/* Build a COMPOUND_EXPR which when expanded will generate the code /* Build a COMPOUND_EXPR which when expanded will generate the code
needed to initialize all the virtual function table slots of all needed to initialize all the virtual function table slots of all
the virtual baseclasses. FOR_TYPE is the type which determines the the virtual baseclasses. MAIN_BINFO is the binfo which determines
virtual baseclasses to use; TYPE is the type of the object to which the virtual baseclasses to use; TYPE is the type of the object to
the initialization applies. TRUE_EXP is the true object we are which the initialization applies. TRUE_EXP is the true object we
initializing, and DECL_PTR is the pointer to the sub-object we are initializing, and DECL_PTR is the pointer to the sub-object we
are initializing. are initializing.
When USE_COMPUTED_OFFSETS is non-zero, we can assume that the When USE_COMPUTED_OFFSETS is non-zero, we can assume that the
object was laidout by a top-level contructor and the computed object was laidout by a top-level contructor and the computed
offsets are valid to store vtables. When zero, we must store new offsets are valid to store vtables. When zero, we must store new
vtables through virtual baseclass pointers. */ vtables through virtual baseclass pointers.
We setup and use the globals: vbase_decl, vbase_decl_ptr, vbase_types
ICK! */
void void
expand_vbase_vtables_init (main_binfo, binfo, true_exp, decl_ptr, expand_indirect_vtbls_init (binfo, true_exp, decl_ptr, use_computed_offsets)
use_computed_offsets) tree binfo;
tree main_binfo, binfo;
tree true_exp, decl_ptr; tree true_exp, decl_ptr;
int use_computed_offsets; int use_computed_offsets;
{ {
tree for_type = BINFO_TYPE (main_binfo);
tree type = BINFO_TYPE (binfo); tree type = BINFO_TYPE (binfo);
if (TYPE_USES_VIRTUAL_BASECLASSES (type)) if (TYPE_USES_VIRTUAL_BASECLASSES (type))
{ {
int old_flag = flag_this_is_variable; int old_flag = flag_this_is_variable;
tree vbases = CLASSTYPE_VBASECLASSES (type); tree vbases = CLASSTYPE_VBASECLASSES (type);
vbase_types = vbases;
vbase_types = CLASSTYPE_VBASECLASSES (for_type);
vbase_decl_ptr = true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0) : decl_ptr; vbase_decl_ptr = true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0) : decl_ptr;
vbase_decl = true_exp ? true_exp : build_indirect_ref (decl_ptr, NULL_PTR); vbase_decl = true_exp ? true_exp : build_indirect_ref (decl_ptr, NULL_PTR);
...@@ -2504,38 +2498,25 @@ expand_vbase_vtables_init (main_binfo, binfo, true_exp, decl_ptr, ...@@ -2504,38 +2498,25 @@ expand_vbase_vtables_init (main_binfo, binfo, true_exp, decl_ptr,
{ {
/* This is an object of type IN_TYPE, */ /* This is an object of type IN_TYPE, */
flag_this_is_variable = -2; flag_this_is_variable = -2;
dfs_walk (main_binfo, dfs_find_vbases, unmarked_new_vtablep); dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep);
} }
/* Initialized with vtables of type TYPE. */ /* Initialized with vtables of type TYPE. */
while (vbases) while (vbases)
{ {
/* This time through, not every class's vtable tree addr;
is going to be initialized. That is, we only initialize if (use_computed_offsets)
the "last" vtable pointer. */ addr = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbases));
else
if (CLASSTYPE_VSIZE (BINFO_TYPE (vbases))) addr = convert_pointer_to (vbases, vbase_decl_ptr);
{ if (addr == error_mark_node)
tree addr; continue;
tree vtbl = BINFO_VTABLE (vbases);
tree init = build_unary_op (ADDR_EXPR, vtbl, 0);
if (!flag_vtable_thunks)
assemble_external (vtbl);
TREE_USED (vtbl) = 1;
if (use_computed_offsets)
addr = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbases));
else
addr = convert_pointer_to (vbases, vbase_decl_ptr);
if (addr) /* Do all vtables from this virtual base. */
{ /* This assumes that virtual bases can never serve as parent
tree ref = build_vfield_ref (build_indirect_ref (addr, NULL_PTR), binfos. (in the CLASSTPE_VFIELD_PARENT sense) */
BINFO_TYPE (vbases)); expand_direct_vtbls_init (vbases, TYPE_BINFO (BINFO_TYPE (vbases)),
init = convert_force (TREE_TYPE (ref), init); 1, 0, addr);
expand_expr_stmt (build_modify_expr (ref, NOP_EXPR, init));
}
}
vbases = TREE_CHAIN (vbases); vbases = TREE_CHAIN (vbases);
} }
...@@ -3114,46 +3095,6 @@ pop_class_decls (type) ...@@ -3114,46 +3095,6 @@ pop_class_decls (type)
search_stack = pop_search_level (search_stack); search_stack = pop_search_level (search_stack);
} }
static int
bfs_unmark_finished_struct (binfo, i)
tree binfo;
int i;
{
if (i >= 0)
binfo = BINFO_BASETYPE (binfo, i);
if (BINFO_NEW_VTABLE_MARKED (binfo))
{
tree decl, context;
if (TREE_VIA_VIRTUAL (binfo))
binfo = binfo_member (BINFO_TYPE (binfo),
CLASSTYPE_VBASECLASSES (current_class_type));
decl = BINFO_VTABLE (binfo);
context = DECL_CONTEXT (decl);
DECL_CONTEXT (decl) = 0;
if (write_virtuals >= 0
&& DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo))
DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE,
BINFO_VIRTUALS (binfo));
finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
DECL_CONTEXT (decl) = context;
}
CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
return 0;
}
void
unmark_finished_struct (type)
tree type;
{
tree binfo = TYPE_BINFO (type);
bfs_unmark_finished_struct (binfo, -1);
breadth_first_search (binfo, bfs_unmark_finished_struct, bfs_marked_vtable_pathp);
}
void void
print_search_statistics () print_search_statistics ()
{ {
......
...@@ -311,7 +311,8 @@ yylex() ...@@ -311,7 +311,8 @@ yylex()
if (lastiddecl != trrr) if (lastiddecl != trrr)
{ {
lastiddecl = trrr; lastiddecl = trrr;
tmp_token.yylval.ttype = DECL_NESTED_TYPENAME (trrr); if (got_scope)
tmp_token.yylval.ttype = DECL_NESTED_TYPENAME (trrr);
} }
break; break;
case IDENTIFIER: case IDENTIFIER:
...@@ -326,6 +327,7 @@ yylex() ...@@ -326,6 +327,7 @@ yylex()
} }
else else
lastiddecl = trrr; lastiddecl = trrr;
got_scope = NULL_TREE;
/* and fall through to... */ /* and fall through to... */
case TYPENAME: case TYPENAME:
case PTYPENAME: case PTYPENAME:
......
...@@ -585,6 +585,9 @@ layout_vbasetypes (rec, max) ...@@ -585,6 +585,9 @@ layout_vbasetypes (rec, max)
Offsets for immediate nonvirtual baseclasses are also computed here. Offsets for immediate nonvirtual baseclasses are also computed here.
TYPE_BINFO (REC) should be NULL_TREE on entry, and this routine
creates a list of base_binfos in TYPE_BINFO (REC) from BINFOS.
Returns list of virtual base classes in a FIELD_DECL chain. */ Returns list of virtual base classes in a FIELD_DECL chain. */
tree tree
layout_basetypes (rec, binfos) layout_basetypes (rec, binfos)
......
...@@ -662,6 +662,8 @@ comp_target_types (ttl, ttr, nptrs) ...@@ -662,6 +662,8 @@ comp_target_types (ttl, ttr, nptrs)
ttr = TYPE_MAIN_VARIANT (ttr); ttr = TYPE_MAIN_VARIANT (ttr);
if (ttl == ttr) if (ttl == ttr)
return 1; return 1;
if (TREE_CODE (ttr) == TEMPLATE_TYPE_PARM)
return 1;
if (TREE_CODE (ttr) != TREE_CODE (ttl)) if (TREE_CODE (ttr) != TREE_CODE (ttl))
return 0; return 0;
...@@ -877,6 +879,9 @@ comp_target_parms (parms1, parms2, strict) ...@@ -877,6 +879,9 @@ comp_target_parms (parms1, parms2, strict)
p2 = TREE_VALUE (t2); p2 = TREE_VALUE (t2);
if (p1 == p2) if (p1 == p2)
continue; continue;
if (TREE_CODE (p2) == TEMPLATE_TYPE_PARM)
continue;
if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE) if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE)
|| (TREE_CODE (p1) == REFERENCE_TYPE && TREE_CODE (p2) == REFERENCE_TYPE)) || (TREE_CODE (p1) == REFERENCE_TYPE && TREE_CODE (p2) == REFERENCE_TYPE))
{ {
...@@ -885,6 +890,9 @@ comp_target_parms (parms1, parms2, strict) ...@@ -885,6 +890,9 @@ comp_target_parms (parms1, parms2, strict)
== TYPE_MAIN_VARIANT (TREE_TYPE (p2)))) == TYPE_MAIN_VARIANT (TREE_TYPE (p2))))
continue; continue;
if (TREE_CODE (TREE_TYPE (p2)) == TEMPLATE_TYPE_PARM)
continue;
/* The following is wrong for contravariance, /* The following is wrong for contravariance,
but many programs depend on it. */ but many programs depend on it. */
if (TREE_TYPE (p1) == void_type_node) if (TREE_TYPE (p1) == void_type_node)
...@@ -4591,24 +4599,28 @@ build_conditional_expr (ifexp, op1, op2) ...@@ -4591,24 +4599,28 @@ build_conditional_expr (ifexp, op1, op2)
else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE) else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
{ {
if (!integer_zerop (op2)) if (!integer_zerop (op2))
warning ("pointer/integer type mismatch in conditional expression"); pedwarn ("pointer/integer type mismatch in conditional expression");
else else
{ {
op2 = null_pointer_node; op2 = null_pointer_node;
#if 0 /* Sez who? */
if (pedantic && TREE_CODE (type1) == FUNCTION_TYPE) if (pedantic && TREE_CODE (type1) == FUNCTION_TYPE)
pedwarn ("ANSI C++ forbids conditional expr between 0 and function pointer"); pedwarn ("ANSI C++ forbids conditional expr between 0 and function pointer");
#endif
} }
result_type = type1; result_type = type1;
} }
else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE) else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
{ {
if (!integer_zerop (op1)) if (!integer_zerop (op1))
warning ("pointer/integer type mismatch in conditional expression"); pedwarn ("pointer/integer type mismatch in conditional expression");
else else
{ {
op1 = null_pointer_node; op1 = null_pointer_node;
#if 0 /* Sez who? */
if (pedantic && TREE_CODE (type2) == FUNCTION_TYPE) if (pedantic && TREE_CODE (type2) == FUNCTION_TYPE)
pedwarn ("ANSI C++ forbids conditional expr between 0 and function pointer"); pedwarn ("ANSI C++ forbids conditional expr between 0 and function pointer");
#endif
} }
result_type = type2; result_type = type2;
op1 = null_pointer_node; op1 = null_pointer_node;
...@@ -6186,19 +6198,19 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) ...@@ -6186,19 +6198,19 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
{ {
if (fndecl) if (fndecl)
cp_warning ("passing `%T' as argument %P of `%D' discards const", cp_pedwarn ("passing `%T' as argument %P of `%D' discards const",
rhstype, parmnum, fndecl); rhstype, parmnum, fndecl);
else else
cp_warning ("%s to `%T' from `%T' discards const", cp_pedwarn ("%s to `%T' from `%T' discards const",
errtype, type, rhstype); errtype, type, rhstype);
} }
if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
{ {
if (fndecl) if (fndecl)
cp_warning ("passing `%T' as argument %P of `%D' discards volatile", cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile",
rhstype, parmnum, fndecl); rhstype, parmnum, fndecl);
else else
cp_warning ("%s to `%T' from `%T' discards volatile", cp_pedwarn ("%s to `%T' from `%T' discards volatile",
errtype, type, rhstype); errtype, type, rhstype);
} }
} }
...@@ -6244,19 +6256,19 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) ...@@ -6244,19 +6256,19 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
{ {
if (fndecl) if (fndecl)
cp_warning ("passing `%T' as argument %P of `%D' discards const", cp_pedwarn ("passing `%T' as argument %P of `%D' discards const",
rhstype, parmnum, fndecl); rhstype, parmnum, fndecl);
else else
cp_warning ("%s to `%T' from `%T' discards const", cp_pedwarn ("%s to `%T' from `%T' discards const",
errtype, type, rhstype); errtype, type, rhstype);
} }
if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
{ {
if (fndecl) if (fndecl)
cp_warning ("passing `%T' as argument %P of `%D' discards volatile", cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile",
rhstype, parmnum, fndecl); rhstype, parmnum, fndecl);
else else
cp_warning ("%s to `%T' from `%T' discards volatile", cp_pedwarn ("%s to `%T' from `%T' discards volatile",
errtype, type, rhstype); errtype, type, rhstype);
} }
} }
......
...@@ -329,7 +329,7 @@ ack (s, v, v2) ...@@ -329,7 +329,7 @@ ack (s, v, v2)
silly. So instead, we just do the equivalent of a call to fatal in the silly. So instead, we just do the equivalent of a call to fatal in the
same situation (call exit). */ same situation (call exit). */
/* First used: 0 (reserved), Last used: 355. Free: 180. */ /* First used: 0 (reserved), Last used: 357. Free: */
static int abortcount = 0; static int abortcount = 0;
...@@ -707,56 +707,6 @@ digest_init (type, init, tail) ...@@ -707,56 +707,6 @@ digest_init (type, init, tail)
return element; return element;
} }
/* Check for initializing a union by its first field.
Such an initializer must use braces. */
if (code == UNION_TYPE)
{
tree result, field = TYPE_FIELDS (type);
/* Find the first named field. ANSI decided in September 1990
that only named fields count here. */
while (field && DECL_NAME (field) == 0)
field = TREE_CHAIN (field);
if (field == 0)
{
error ("union with no named members cannot be initialized");
return error_mark_node;
}
if (raw_constructor && !TYPE_NEEDS_CONSTRUCTING (type))
{
result = process_init_constructor (type, init, NULL_PTR);
return result;
}
if (! raw_constructor)
{
error ("type mismatch in initialization");
return error_mark_node;
}
if (element == 0)
{
if (!TYPE_NEEDS_CONSTRUCTING (type))
{
error ("union initializer requires one element");
return error_mark_node;
}
}
else
{
/* Take just the first element from within the constructor
and it should match the type of the first element. */
element = digest_init (TREE_TYPE (field), element, (tree *) 0);
result = build (CONSTRUCTOR, type, 0, build_tree_list (field, element));
TREE_CONSTANT (result) = TREE_CONSTANT (element);
TREE_STATIC (result) = (initializer_constant_valid_p (element)
&& TREE_CONSTANT (element));
return result;
}
}
/* Initialization of an array of chars from a string constant /* Initialization of an array of chars from a string constant
optionally enclosed in braces. */ optionally enclosed in braces. */
...@@ -834,7 +784,8 @@ digest_init (type, init, tail) ...@@ -834,7 +784,8 @@ digest_init (type, init, tail)
if (TYPE_SIZE (type) && ! TREE_CONSTANT (TYPE_SIZE (type))) if (TYPE_SIZE (type) && ! TREE_CONSTANT (TYPE_SIZE (type)))
{ {
error ("variable-sized object may not be initialized"); cp_error ("variable-sized object of type `%T' may not be initialized",
type);
return error_mark_node; return error_mark_node;
} }
...@@ -1097,6 +1048,12 @@ process_init_constructor (type, init, elts) ...@@ -1097,6 +1048,12 @@ process_init_constructor (type, init, elts)
if (!win) if (!win)
TREE_VALUE (tail) = error_mark_node; TREE_VALUE (tail) = error_mark_node;
} }
else if (field == 0)
{
cp_error ("union `%T' with no named members cannot be initialized",
type);
TREE_VALUE (tail) = error_mark_node;
}
if (TREE_VALUE (tail) != 0) if (TREE_VALUE (tail) != 0)
{ {
...@@ -1105,7 +1062,7 @@ process_init_constructor (type, init, elts) ...@@ -1105,7 +1062,7 @@ process_init_constructor (type, init, elts)
next1 = digest_init (TREE_TYPE (field), next1 = digest_init (TREE_TYPE (field),
TREE_VALUE (tail), &tail1); TREE_VALUE (tail), &tail1);
if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST)
abort (); my_friendly_abort (357);
tail = tail1; tail = tail1;
} }
else else
...@@ -1129,7 +1086,7 @@ process_init_constructor (type, init, elts) ...@@ -1129,7 +1086,7 @@ process_init_constructor (type, init, elts)
/* If arguments were specified as a constructor, /* If arguments were specified as a constructor,
complain unless we used all the elements of the constructor. */ complain unless we used all the elements of the constructor. */
else if (tail) else if (tail)
warning ("excess elements in aggregate initializer"); pedwarn ("excess elements in aggregate initializer");
if (erroneous) if (erroneous)
return error_mark_node; return error_mark_node;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment