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)
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);
}
......@@ -3975,7 +3976,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
return error_mark_node;
}
if (! TREE_OVERLOADED (fnname))
if (TREE_CODE (functions) == FUNCTION_DECL)
{
functions = DECL_MAIN_VARIANT (functions);
if (final_cp)
......
......@@ -1071,11 +1071,11 @@ struct lang_decl
or virtual baseclasses. */
#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
should be looked up in a non-standard way. */
#define TREE_OVERLOADED(NODE) (TREE_LANG_FLAG_0 (NODE))
#if 0 /* UNUSED */
#define DECL_OVERLOADED(NODE) (DECL_LANG_FLAG_4 (NODE))
#define DECL_OVERLOADED(NODE) (NOTHING)
#endif
/* Nonzero if this (non-TYPE)_DECL has its virtual attribute set.
......@@ -1251,7 +1251,13 @@ struct lang_decl
#define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT(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. */
#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;
extern tree exception_type_node, unknown_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 *)[]' */
extern tree vtbl_type_node;
extern tree delta_type_node;
......@@ -1952,7 +1950,7 @@ extern tree build_dynamic_cast PROTO((tree, tree));
/* in init.c */
extern void emit_base_init PROTO((tree, int));
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 expand_member_init PROTO((tree, tree, tree));
extern void expand_aggr_init PROTO((tree, tree, int));
......@@ -2101,12 +2099,12 @@ extern tree lookup_nested_tag PROTO((tree, tree));
extern HOST_WIDE_INT breadth_first_search PROTO((tree, int (*)(), int (*)()));
extern int tree_needs_constructor_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_baselinks PROTO((tree, tree, tree));
extern tree next_baselink PROTO((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 tree get_vbase_types PROTO((tree));
extern void build_mi_matrix PROTO((tree));
......
......@@ -706,10 +706,11 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
else if (form == REFERENCE_TYPE)
{
rval = copy_node (expr);
TREE_TYPE (rval) = build_pointer_type (TREE_TYPE (TREE_TYPE (expr)));
rval = build1 (NOP_EXPR,
build_pointer_type (TREE_TYPE (TREE_TYPE (expr))),
expr);
rval = convert (build_pointer_type (TREE_TYPE (reftype)), rval);
TREE_TYPE (rval) = reftype;
rval = build1 (NOP_EXPR, reftype, rval);
return rval;
}
......@@ -734,7 +735,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
if (rval != error_mark_node)
rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), rval);
if (rval != error_mark_node)
TREE_TYPE (rval) = reftype;
rval = build1 (NOP_EXPR, reftype, rval);
}
else if (decl == error_mark_node || decl == NULL_TREE)
{
......@@ -1146,9 +1147,8 @@ convert_pointer_to_real (binfo, expr)
but if it is, give them an error message that they can read. */
if (distance < 0)
{
cp_error ("cannot convert a pointer of type `%T'",
TREE_TYPE (intype));
cp_error ("to a pointer of type `%T'", type);
cp_error ("cannot convert a pointer of type `%T' to a pointer of type `%T'",
TREE_TYPE (intype), type);
if (distance == -2)
cp_error ("because `%T' is an ambiguous base class", type);
......
......@@ -1381,6 +1381,10 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree)
if (DECL_FRIEND_P (value))
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;
return value;
}
......@@ -2307,6 +2311,37 @@ mark_vtable_entries (decl)
tree fnaddr = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries));
tree fn = TREE_OPERAND (fnaddr, 0);
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)
tree prev, vars;
{
tree ctype = DECL_CONTEXT (vars);
import_export_vtable (vars, ctype);
if (flag_vtable_thunks && !CLASSTYPE_INTERFACE_KNOWN (ctype))
{
tree method;
......@@ -2578,6 +2615,10 @@ finish_file ()
lineno = DECL_SOURCE_LINE (decl);
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 (TREE_CODE (init) == VAR_DECL)
......@@ -2615,19 +2656,7 @@ finish_file ()
if (IS_AGGR_TYPE (TREE_TYPE (decl))
|| init == 0
|| TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
{
#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
}
expand_aggr_init (decl, init, 0);
else if (TREE_CODE (init) == TREE_VEC)
{
expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0),
......@@ -2638,6 +2667,8 @@ finish_file ()
}
else
expand_assignment (decl, init, 0, 0);
DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE;
}
else if (TREE_CODE (decl) == SAVE_EXPR)
{
......
......@@ -186,8 +186,7 @@ dump_type (t, v)
break;
case TYPE_DECL:
dump_readonly_or_volatile (t, after);
OB_PUTID (DECL_NAME (t));
dump_decl (t, v);
break;
case INTEGER_TYPE:
......@@ -553,6 +552,17 @@ dump_decl (t, v)
OB_PUTS (" /* decl error */ ");
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:
if (VTABLE_NAME_P (DECL_NAME (t)))
{
......@@ -563,10 +573,11 @@ dump_decl (t, v)
/* else fall through */
case FIELD_DECL:
case PARM_DECL:
general:
if (v > 0)
{
dump_type_prefix (TREE_TYPE (t), v);
OB_PUTC(' ');
OB_PUTC (' ');
}
/* DECL_CLASS_CONTEXT isn't being set in some cases. Hmm... */
if (TREE_CODE (t) == FIELD_DECL
......@@ -574,13 +585,14 @@ dump_decl (t, v)
&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't'))
{
dump_type (DECL_CONTEXT (t), 0);
OB_PUTC2(':', ':');
OB_PUTC2 (':', ':');
}
if (DECL_NAME (t))
dump_decl (DECL_NAME (t), v);
else
OB_PUTS ("{anon}");
if (v > 0) dump_type_suffix (TREE_TYPE (t), v);
if (v > 0)
dump_type_suffix (TREE_TYPE (t), v);
break;
case ARRAY_REF:
......@@ -598,10 +610,6 @@ dump_decl (t, v)
dump_type (t, v);
break;
case TYPE_DECL:
dump_type (TREE_TYPE (t), v);
break;
case TYPE_EXPR:
my_friendly_abort (69);
break;
......
......@@ -1162,11 +1162,13 @@ do_pending_inlines ()
/* Pass back a handle on the rest of the inline functions, so that they
can be processed later. */
yylval.ttype = build_tree_list ((tree) t, t->fndecl);
#if 0
if (flag_default_inline && t->fndecl
/* If we're working from a template, don't change
the `inline' state. */
&& t->parm_vec == NULL_TREE)
DECL_INLINE (t->fndecl) = 1;
#endif
DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
}
......@@ -1215,11 +1217,13 @@ process_next_inline (t)
input_filename = i->filename;
yychar = PRE_PARSED_FUNCTION_DECL;
yylval.ttype = build_tree_list ((tree) i, i->fndecl);
#if 0
if (flag_default_inline
/* If we're working from a template, don't change
the `inline' state. */
&& i->parm_vec == NULL_TREE)
DECL_INLINE (i->fndecl) = 1;
#endif
DECL_PENDING_INLINE_INFO (i->fndecl) = 0;
}
if (i)
......@@ -2577,7 +2581,7 @@ check_newline ()
else
error ("`#pragma implementation' can only appear at top-level");
interface_only = 0;
#if 0
#if 1
/* We make this non-zero so that we infer decl linkage
in the impl file only for variables first declared
in the interface file. */
......@@ -4576,6 +4580,7 @@ build_lang_decl (code, name, type)
if (current_lang_name == lang_name_cplusplus)
{
DECL_LANGUAGE (t) = lang_cplusplus;
#if 0
#ifndef NO_AUTO_OVERLOAD
if (code == FUNCTION_DECL && name != 0
&& ! (IDENTIFIER_LENGTH (name) == 4
......@@ -4587,6 +4592,7 @@ build_lang_decl (code, name, type)
&& strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0))
TREE_OVERLOADED (name) = 1;
#endif
#endif
}
else if (current_lang_name == lang_name_c)
DECL_LANGUAGE (t) = lang_c;
......
......@@ -111,8 +111,10 @@ do_inline_function_hair (type, friend_list)
args = TREE_CHAIN (args);
}
/* Allow this decl to be seen in global scope */
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method;
/* Allow this decl to be seen in global scope. Don't do this for
local class methods, though. */
if (! current_function_decl)
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method;
}
method = TREE_CHAIN (method);
}
......@@ -1698,6 +1700,7 @@ emit_thunk (thunk_fndecl)
int delta = THUNK_DELTA (thunk_fndecl);
int tem;
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. */
rtx need_use[FIRST_PSEUDO_REGISTER];
......
......@@ -779,8 +779,9 @@ identifier_defn:
explicit_instantiation:
TEMPLATE aggr template_type
{ do_type_instantiation ($3); }
| TEMPLATE typed_declspecs declarator
{ do_function_instantiation ($2, $3); }
{ do_function_instantiation ($2, $3); }
;
template_type:
......@@ -844,6 +845,8 @@ template_instantiate_once:
pop_obstacks ();
pushdecl_top_level (decl);
}
/* Kludge; see instantiate_class_template. */
TYPE_BEING_DEFINED (t) = 0;
}
left_curly opt.component_decl_list '}'
{
......
......@@ -1013,6 +1013,8 @@ instantiate_class_template (classname, setup_parse)
/* Get interface/implementation back in sync. */
extract_interface_info ();
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;
yylval.ttype = classname;
processing_template_defn++;
......@@ -2187,6 +2189,10 @@ do_pending_expansions ()
|| TREE_CODE (t) == VAR_DECL, 294);
if (TREE_ASM_WRITTEN (t))
DECIDE (0);
if (DECL_EXPLICITLY_INSTANTIATED (t))
DECIDE (1);
/* If it's a method, let the class type decide it.
@@ What if the method template is in a separate file?
Maybe both file contexts should be taken into account?
......@@ -2311,8 +2317,29 @@ do_function_instantiation (declspecs, declarator)
}
}
}
if (!result)
if (! result)
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
......
......@@ -687,6 +687,22 @@ lookup_field_1 (type, name)
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
current_scope ()
{
......@@ -1842,14 +1858,14 @@ int tree_has_any_destructor_p (binfo, i)
return TYPE_NEEDS_DESTRUCTOR (type);
}
/* Given a class type TYPE, and a function decl FNDECL,
look for the first function the TYPE's hierarchy which
FNDECL could match as a virtual function.
/* Given a class type TYPE, and a function decl FNDECL, look for a
virtual function in TYPE's hierarchy which FNDECL could match as a
virtual function. It doesn't matter which one we find.
DTORP is nonzero if we are looking for a destructor. Destructors
need special treatment because they do not match by name. */
tree
get_first_matching_virtual (binfo, fndecl, dtorp)
get_matching_virtual (binfo, fndecl, dtorp)
tree binfo, fndecl;
int dtorp;
{
......@@ -1863,22 +1879,11 @@ get_first_matching_virtual (binfo, fndecl, dtorp)
tmp = get_virtual_destructor (binfo, -1);
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;
tmp = (tree) breadth_first_search (binfo,
(pfi) get_virtual_destructor,
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;
}
else
......@@ -1931,33 +1936,20 @@ get_first_matching_virtual (binfo, fndecl, dtorp)
}
if (tmp)
{
/* If this is ambiguous, we will warn about it later. */
if (best)
{
if (get_base_distance (DECL_CLASS_CONTEXT (best),
DECL_CLASS_CONTEXT (tmp), 0, 0) > 0)
best = tmp;
}
else
best = tmp;
best = tmp;
break;
}
}
if (best == NULL_TREE && warn_overloaded_virtual)
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 the list of virtual functions which are abstract in type TYPE
that come from non virtual base classes. See init_vtbl_ptrs for
the style of search we do. */
/* Return the list of virtual functions which are abstract in type
TYPE that come from non virtual base classes. See
expand_direct_vtbls_init for the style of search we do. */
static tree
get_abstract_virtuals_1 (binfo, do_self, abstract_virtuals)
tree binfo, abstract_virtuals;
......@@ -2364,7 +2356,9 @@ dfs_debug_mark (binfo)
}
/* 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
dfs_find_vbases (binfo)
tree binfo;
......@@ -2471,32 +2465,32 @@ init_vbase_pointers (type, decl_ptr)
/* Build a COMPOUND_EXPR which when expanded will generate the code
needed to initialize all the virtual function table slots of all
the virtual baseclasses. FOR_TYPE is the type which determines the
virtual baseclasses to use; TYPE is the type of the object to which
the initialization applies. TRUE_EXP is the true object we are
initializing, and DECL_PTR is the pointer to the sub-object we
the virtual baseclasses. MAIN_BINFO is the binfo which determines
the virtual baseclasses to use; TYPE is the type of the object to
which the initialization applies. TRUE_EXP is the true object we
are initializing, and DECL_PTR is the pointer to the sub-object we
are initializing.
When USE_COMPUTED_OFFSETS is non-zero, we can assume that the
object was laidout by a top-level contructor and the computed
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
expand_vbase_vtables_init (main_binfo, binfo, true_exp, decl_ptr,
use_computed_offsets)
tree main_binfo, binfo;
expand_indirect_vtbls_init (binfo, true_exp, decl_ptr, use_computed_offsets)
tree binfo;
tree true_exp, decl_ptr;
int use_computed_offsets;
{
tree for_type = BINFO_TYPE (main_binfo);
tree type = BINFO_TYPE (binfo);
if (TYPE_USES_VIRTUAL_BASECLASSES (type))
{
int old_flag = flag_this_is_variable;
tree vbases = CLASSTYPE_VBASECLASSES (type);
vbase_types = CLASSTYPE_VBASECLASSES (for_type);
vbase_types = vbases;
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);
......@@ -2504,38 +2498,25 @@ expand_vbase_vtables_init (main_binfo, binfo, true_exp, decl_ptr,
{
/* This is an object of type IN_TYPE, */
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. */
while (vbases)
{
/* This time through, not every class's vtable
is going to be initialized. That is, we only initialize
the "last" vtable pointer. */
if (CLASSTYPE_VSIZE (BINFO_TYPE (vbases)))
{
tree addr;
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);
tree addr;
if (use_computed_offsets)
addr = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbases));
else
addr = convert_pointer_to (vbases, vbase_decl_ptr);
if (addr == error_mark_node)
continue;
if (addr)
{
tree ref = build_vfield_ref (build_indirect_ref (addr, NULL_PTR),
BINFO_TYPE (vbases));
init = convert_force (TREE_TYPE (ref), init);
expand_expr_stmt (build_modify_expr (ref, NOP_EXPR, init));
}
}
/* Do all vtables from this virtual base. */
/* This assumes that virtual bases can never serve as parent
binfos. (in the CLASSTPE_VFIELD_PARENT sense) */
expand_direct_vtbls_init (vbases, TYPE_BINFO (BINFO_TYPE (vbases)),
1, 0, addr);
vbases = TREE_CHAIN (vbases);
}
......@@ -3114,46 +3095,6 @@ pop_class_decls (type)
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
print_search_statistics ()
{
......
......@@ -311,7 +311,8 @@ yylex()
if (lastiddecl != trrr)
{
lastiddecl = trrr;
tmp_token.yylval.ttype = DECL_NESTED_TYPENAME (trrr);
if (got_scope)
tmp_token.yylval.ttype = DECL_NESTED_TYPENAME (trrr);
}
break;
case IDENTIFIER:
......@@ -326,6 +327,7 @@ yylex()
}
else
lastiddecl = trrr;
got_scope = NULL_TREE;
/* and fall through to... */
case TYPENAME:
case PTYPENAME:
......
......@@ -585,6 +585,9 @@ layout_vbasetypes (rec, max)
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. */
tree
layout_basetypes (rec, binfos)
......
......@@ -662,6 +662,8 @@ comp_target_types (ttl, ttr, nptrs)
ttr = TYPE_MAIN_VARIANT (ttr);
if (ttl == ttr)
return 1;
if (TREE_CODE (ttr) == TEMPLATE_TYPE_PARM)
return 1;
if (TREE_CODE (ttr) != TREE_CODE (ttl))
return 0;
......@@ -877,6 +879,9 @@ comp_target_parms (parms1, parms2, strict)
p2 = TREE_VALUE (t2);
if (p1 == p2)
continue;
if (TREE_CODE (p2) == TEMPLATE_TYPE_PARM)
continue;
if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE)
|| (TREE_CODE (p1) == REFERENCE_TYPE && TREE_CODE (p2) == REFERENCE_TYPE))
{
......@@ -885,6 +890,9 @@ comp_target_parms (parms1, parms2, strict)
== TYPE_MAIN_VARIANT (TREE_TYPE (p2))))
continue;
if (TREE_CODE (TREE_TYPE (p2)) == TEMPLATE_TYPE_PARM)
continue;
/* The following is wrong for contravariance,
but many programs depend on it. */
if (TREE_TYPE (p1) == void_type_node)
......@@ -4591,24 +4599,28 @@ build_conditional_expr (ifexp, op1, op2)
else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
{
if (!integer_zerop (op2))
warning ("pointer/integer type mismatch in conditional expression");
pedwarn ("pointer/integer type mismatch in conditional expression");
else
{
op2 = null_pointer_node;
#if 0 /* Sez who? */
if (pedantic && TREE_CODE (type1) == FUNCTION_TYPE)
pedwarn ("ANSI C++ forbids conditional expr between 0 and function pointer");
#endif
}
result_type = type1;
}
else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
if (!integer_zerop (op1))
warning ("pointer/integer type mismatch in conditional expression");
pedwarn ("pointer/integer type mismatch in conditional expression");
else
{
op1 = null_pointer_node;
#if 0 /* Sez who? */
if (pedantic && TREE_CODE (type2) == FUNCTION_TYPE)
pedwarn ("ANSI C++ forbids conditional expr between 0 and function pointer");
#endif
}
result_type = type2;
op1 = null_pointer_node;
......@@ -6186,19 +6198,19 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
{
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);
else
cp_warning ("%s to `%T' from `%T' discards const",
cp_pedwarn ("%s to `%T' from `%T' discards const",
errtype, type, rhstype);
}
if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
{
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);
else
cp_warning ("%s to `%T' from `%T' discards volatile",
cp_pedwarn ("%s to `%T' from `%T' discards volatile",
errtype, type, rhstype);
}
}
......@@ -6244,19 +6256,19 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
{
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);
else
cp_warning ("%s to `%T' from `%T' discards const",
cp_pedwarn ("%s to `%T' from `%T' discards const",
errtype, type, rhstype);
}
if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
{
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);
else
cp_warning ("%s to `%T' from `%T' discards volatile",
cp_pedwarn ("%s to `%T' from `%T' discards volatile",
errtype, type, rhstype);
}
}
......
......@@ -329,7 +329,7 @@ ack (s, v, v2)
silly. So instead, we just do the equivalent of a call to fatal in the
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;
......@@ -707,56 +707,6 @@ digest_init (type, init, tail)
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
optionally enclosed in braces. */
......@@ -834,7 +784,8 @@ digest_init (type, init, tail)
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;
}
......@@ -1097,6 +1048,12 @@ process_init_constructor (type, init, elts)
if (!win)
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)
{
......@@ -1105,7 +1062,7 @@ process_init_constructor (type, init, elts)
next1 = digest_init (TREE_TYPE (field),
TREE_VALUE (tail), &tail1);
if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST)
abort ();
my_friendly_abort (357);
tail = tail1;
}
else
......@@ -1129,7 +1086,7 @@ process_init_constructor (type, init, elts)
/* If arguments were specified as a constructor,
complain unless we used all the elements of the constructor. */
else if (tail)
warning ("excess elements in aggregate initializer");
pedwarn ("excess elements in aggregate initializer");
if (erroneous)
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