parent
fd67d2b620
commit
a292b002ee
148
gcc/cp/ChangeLog
148
gcc/cp/ChangeLog
|
@ -1,18 +1,148 @@
|
|||
Fri Aug 5 01:12:20 1994 Mike Stump (mrs@cygnus.com)
|
||||
|
||||
* class.c (get_class_offset_1, get_class_offset): New routine to
|
||||
find the offset of the class where a virtual function is defined,
|
||||
from the complete type.
|
||||
* class.c (modify_one_vtable, fixup_vtable_deltas): Use
|
||||
get_class_offset instead of virtual_offset as get_class_offset will
|
||||
always provide the right answer.
|
||||
* tree.c (virtual_offset): Remove. It only ever worked some of the
|
||||
time.
|
||||
|
||||
Tue Aug 2 12:44:21 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* call.c (build_method_call): Put back unary_complex_lvalue call
|
||||
that I thought was redundant.
|
||||
|
||||
* typeck.c (c_expand_return): Fix a case I missed before.
|
||||
|
||||
Sun Jul 31 17:54:02 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* pt.c (unify): Strip cv-quals from template type arguments (when
|
||||
'const T*' is matched to 'const char*', that does not mean that T is
|
||||
'const char').
|
||||
|
||||
Fri Jul 29 01:03:06 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* pt.c (do_type_instantiation): Instantiate nested TAGS, not
|
||||
typedefs. Third time's the charm?
|
||||
|
||||
* parse.y (template_parm): Support default template parms.
|
||||
* pt.c (process_template_parm): Ditto.
|
||||
(end_template_parm_list): Ditto.
|
||||
(coerce_template_parms): Ditto.
|
||||
(mangle_class_name_for_template): Ditto.
|
||||
(push_template_decls): Ditto.
|
||||
(unify): Ditto.
|
||||
* method.c (build_overload_identifier): Ditto.
|
||||
* error.c (dump_decl): Ditto.
|
||||
|
||||
Wed Jul 27 17:47:00 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* pt.c (do_type_instantiation): Only instantiate nested *classes*.
|
||||
|
||||
Tue Jul 26 13:22:40 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* search.c (note_debug_info_needed): Also emit debugging information
|
||||
for the types of fields.
|
||||
|
||||
Mon Jul 25 00:34:44 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* pt.c (lookup_template_class): Pass 'template' to
|
||||
coerce_template_parms instead of 'in_decl', since it's a more
|
||||
meaningful context.
|
||||
|
||||
* typeck.c (c_expand_return): Make sure any cleanups for the return
|
||||
expression get run.
|
||||
(build_c_cast): Use CONVERT_EXPR for conversion to void.
|
||||
|
||||
* pt.c (do_type_instantiation): Also instantiate nested types.
|
||||
|
||||
* typeck.c (convert_for_assignment): Don't die when comparing
|
||||
pointers with different levels of indirection.
|
||||
|
||||
* decl.c (grokdeclarator): The sub-call to grokdeclarator for
|
||||
class-local typedefs sets DECL_ARGUMENTS, so we need to clear it
|
||||
out.
|
||||
|
||||
* decl2.c (finish_anon_union): Don't die if the union has no
|
||||
members.
|
||||
|
||||
* decl.c (grokdeclarator): Undo changes to declspecs when we're done
|
||||
so that 'typedef int foo, bar;' will work.
|
||||
|
||||
* decl2.c (finish_file): Don't call expand_aggr_init for
|
||||
non-aggregates.
|
||||
|
||||
Mon Jul 25 00:03:10 1994 Teemu Torma (tot@trema.fi)
|
||||
|
||||
* decl.c (finish_function): We can't inline constructors and
|
||||
destructors under some conditions with -fpic, but don't unset
|
||||
DECL_INLINE.
|
||||
|
||||
Mon Jul 25 00:03:10 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* typeck.c (build_object_ref): Make sure 'datum' is a valid object.
|
||||
|
||||
Sun Jul 24 14:19:31 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* class.c (finish_struct): Don't set DECL_FIELD_BITPOS on
|
||||
non-fields.
|
||||
(finish_struct_methods): Use copy_assignment_arg_p.
|
||||
|
||||
* cvt.c (cp_convert): If expr is an OFFSET_REF, resolve it instead
|
||||
of giving an error.
|
||||
|
||||
* typeck.c (build_binary_op_nodefault): Don't set result_type if we
|
||||
don't know how to compare the operands.
|
||||
|
||||
* decl.c (grokdeclarator): Avoid seg fault when someone uses '__op'
|
||||
as a declarator-id in their program. Like the Linux headers do.
|
||||
Arrgh.
|
||||
|
||||
* tree.c (lvalue_p): Treat calls to functions returning objects by
|
||||
value as lvalues again.
|
||||
|
||||
* typeck.c (build_component_addr): Use convert_force to convert the
|
||||
pointer in case the component type is also a private base class.
|
||||
|
||||
* search.c (get_matching_virtual): Fix bogus warning of overloaded
|
||||
virtual.
|
||||
|
||||
* pt.c (overload_template_name): Set DECL_ARTIFICIAL on the created
|
||||
TYPE_DECL to fix bogus shadowing warnings.
|
||||
|
||||
Fri Jul 22 01:15:32 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* init.c (expand_aggr_init_1): const and volatile mismatches do not
|
||||
prevent a TARGET_EXPR from initializing an object directly.
|
||||
|
||||
Tue Jul 19 17:55:37 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* cvt.c (build_up_reference): Allow building up references to
|
||||
`this', don't warn about making references to artificial variables
|
||||
(like `this').
|
||||
|
||||
* tree.c (lvalue_p): `this' is not an lvalue.
|
||||
|
||||
* call.c (build_method_call): Accept using a typedef name (or
|
||||
template type parameter) for explicit destructor calls.
|
||||
|
||||
Wed Jul 13 03:57:54 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* method.c (hack_identifier): Put back old code so lists of
|
||||
non-functions will be handled properly.
|
||||
* method.c (hack_identifier): Put back old code so lists of
|
||||
non-functions will be handled properly.
|
||||
|
||||
* cp-tree.h (TYPE_NEEDS_CONSTRUCTING): #if 0 out; this macro is now
|
||||
defined in the language-independent tree.h.
|
||||
* cp-tree.h (TYPE_NEEDS_CONSTRUCTING): #if 0 out; this macro is now
|
||||
defined in the language-independent tree.h.
|
||||
|
||||
* tree.c (count_functions): Avoid bogus warning when compiling this
|
||||
function.
|
||||
* tree.c (count_functions): Avoid bogus warning when compiling this
|
||||
function.
|
||||
|
||||
Mon Jul 11 18:37:20 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (grok_reference_init): Always save the initializer of a
|
||||
reference.
|
||||
* decl.c (grok_reference_init): Always save the initializer of a
|
||||
reference.
|
||||
|
||||
Fri Jul 8 17:41:46 1994 Mike Stump (mrs@cygnus.com)
|
||||
|
||||
|
@ -36,7 +166,7 @@ Fri Jul 8 02:27:41 1994 Jason Merrill (jason@deneb.cygnus.com)
|
|||
|
||||
* decl.c (push_overloaded_decl): Don't create overloads of one when
|
||||
shadowing a class type.
|
||||
* typeck.c (build_x_function_call): Complain about overloads of one
|
||||
* typeck.c (build_x_function_call): Complain about overloads of one.
|
||||
|
||||
* decl.c (grokdeclarator): Don't try to treat a char* as a tree.
|
||||
(grokdeclarator): Fix setting of TREE_STATIC.
|
||||
|
|
|
@ -193,7 +193,7 @@ parse.o : $(srcdir)/parse.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
|
|||
`echo $(srcdir)/parse.c | sed 's,^\./,,'`
|
||||
|
||||
$(srcdir)/parse.c $(srcdir)/parse.h : $(srcdir)/parse.y
|
||||
@echo expect 1 shift/reduce confict and 33 reduce/reduce conflicts.
|
||||
@echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts.
|
||||
cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y
|
||||
cd $(srcdir); grep '^#define[ ]*YYEMPTY' parse.c >>parse.h
|
||||
|
||||
|
|
|
@ -1604,21 +1604,15 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
if (parms)
|
||||
error ("destructors take no parameters");
|
||||
basetype = TREE_TYPE (instance);
|
||||
if (IS_AGGR_TYPE (basetype))
|
||||
if (! ((IS_AGGR_TYPE (basetype)
|
||||
&& name == constructor_name (basetype))
|
||||
|| basetype == get_type_value (name)))
|
||||
{
|
||||
if (name == constructor_name (basetype))
|
||||
goto huzzah;
|
||||
cp_error ("destructor name `~%D' does not match type `%T' of expression",
|
||||
name, basetype);
|
||||
return void_zero_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (basetype == get_type_value (name))
|
||||
goto huzzah;
|
||||
}
|
||||
cp_error ("destructor name `~%D' does not match type `%T' of expression",
|
||||
name, basetype);
|
||||
return void_zero_node;
|
||||
|
||||
huzzah:
|
||||
if (! TYPE_HAS_DESTRUCTOR (basetype))
|
||||
return void_zero_node;
|
||||
instance = default_conversion (instance);
|
||||
|
|
111
gcc/cp/class.c
111
gcc/cp/class.c
|
@ -1830,8 +1830,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
|
|||
{
|
||||
tree parmtype = TREE_VALUE (FUNCTION_ARG_CHAIN (fn_fields));
|
||||
|
||||
if (TREE_CODE (parmtype) == REFERENCE_TYPE
|
||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == t)
|
||||
if (copy_assignment_arg_p (parmtype, DECL_VIRTUAL_P (fn_fields)))
|
||||
{
|
||||
if (TREE_PROTECTED (fn_fields))
|
||||
TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 1;
|
||||
|
@ -2151,6 +2150,86 @@ overrides (fndecl, base_fndecl)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static tree
|
||||
get_class_offset_1 (parent, binfo, context, t, fndecl)
|
||||
tree parent, binfo, context, t, fndecl;
|
||||
{
|
||||
tree binfos = BINFO_BASETYPES (binfo);
|
||||
int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
|
||||
tree rval = NULL_TREE;
|
||||
|
||||
if (binfo == parent)
|
||||
return error_mark_node;
|
||||
|
||||
for (i = 0; i < n_baselinks; i++)
|
||||
{
|
||||
tree base_binfo = TREE_VEC_ELT (binfos, i);
|
||||
tree nrval;
|
||||
|
||||
if (TREE_VIA_VIRTUAL (base_binfo))
|
||||
base_binfo = binfo_member (BINFO_TYPE (base_binfo),
|
||||
CLASSTYPE_VBASECLASSES (t));
|
||||
nrval = get_class_offset_1 (parent, base_binfo, context, t, fndecl);
|
||||
/* See if we have a new value */
|
||||
if (nrval && (nrval != error_mark_node || rval==0))
|
||||
{
|
||||
/* Only compare if we have two offsets */
|
||||
if (rval && rval != error_mark_node
|
||||
&& ! tree_int_cst_equal (nrval, rval))
|
||||
{
|
||||
/* Only give error if the two offsets are different */
|
||||
error ("every virtual function must have a unique final overrider");
|
||||
cp_error (" found two (or more) `%T' class subobjects in `%T'", context, t);
|
||||
cp_error (" with virtual `%D' from virtual base class", fndecl);
|
||||
return rval;
|
||||
}
|
||||
rval = nrval;
|
||||
}
|
||||
|
||||
if (rval && BINFO_TYPE (binfo) == context)
|
||||
{
|
||||
my_friendly_assert (rval == error_mark_node
|
||||
|| tree_int_cst_equal (rval, BINFO_OFFSET (binfo)), 999);
|
||||
rval = BINFO_OFFSET (binfo);
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* Get the offset to the CONTEXT subobject that is related to the
|
||||
given BINFO. */
|
||||
static tree
|
||||
get_class_offset (context, t, binfo, fndecl)
|
||||
tree context, t, binfo, fndecl;
|
||||
{
|
||||
tree first_binfo = binfo;
|
||||
tree offset;
|
||||
int i;
|
||||
|
||||
if (context == t)
|
||||
return integer_zero_node;
|
||||
|
||||
if (BINFO_TYPE (binfo) == context)
|
||||
return BINFO_OFFSET (binfo);
|
||||
|
||||
/* Check less derived binfos first. */
|
||||
while (BINFO_BASETYPES (binfo)
|
||||
&& (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1)
|
||||
{
|
||||
tree binfos = BINFO_BASETYPES (binfo);
|
||||
binfo = TREE_VEC_ELT (binfos, i);
|
||||
if (BINFO_TYPE (binfo) == context)
|
||||
return BINFO_OFFSET (binfo);
|
||||
}
|
||||
|
||||
/* Ok, not found in the less derived binfos, now check the more
|
||||
derived binfos. */
|
||||
offset = get_class_offset_1 (first_binfo, TYPE_BINFO (t), context, t, fndecl);
|
||||
if (offset==0 || TREE_CODE (offset) != INTEGER_CST)
|
||||
my_friendly_abort (999); /* we have to find it. */
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void
|
||||
modify_one_vtable (binfo, t, fndecl, pfn)
|
||||
tree binfo, t, fndecl, pfn;
|
||||
|
@ -2174,16 +2253,7 @@ modify_one_vtable (binfo, t, fndecl, pfn)
|
|||
tree vfield = CLASSTYPE_VFIELD (t);
|
||||
tree this_offset;
|
||||
|
||||
offset = integer_zero_node;
|
||||
if (context != t && TYPE_USES_COMPLEX_INHERITANCE (t))
|
||||
{
|
||||
offset = virtual_offset (context, CLASSTYPE_VBASECLASSES (t), offset);
|
||||
if (offset == NULL_TREE)
|
||||
{
|
||||
tree binfo = get_binfo (context, t, 0);
|
||||
offset = BINFO_OFFSET (binfo);
|
||||
}
|
||||
}
|
||||
offset = get_class_offset (context, t, binfo, fndecl);
|
||||
|
||||
/* Find the right offset for the this pointer based on the
|
||||
base class we just found. We have to take into
|
||||
|
@ -2288,16 +2358,7 @@ fixup_vtable_deltas (binfo, t)
|
|||
tree vfield = CLASSTYPE_VFIELD (t);
|
||||
tree this_offset;
|
||||
|
||||
offset = integer_zero_node;
|
||||
if (context != t && TYPE_USES_COMPLEX_INHERITANCE (t))
|
||||
{
|
||||
offset = virtual_offset (context, CLASSTYPE_VBASECLASSES (t), offset);
|
||||
if (offset == NULL_TREE)
|
||||
{
|
||||
tree binfo = get_binfo (context, t, 0);
|
||||
offset = BINFO_OFFSET (binfo);
|
||||
}
|
||||
}
|
||||
offset = get_class_offset (context, t, binfo, fndecl);
|
||||
|
||||
/* Find the right offset for the this pointer based on the
|
||||
base class we just found. We have to take into
|
||||
|
@ -3498,6 +3559,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
tree uelt = TYPE_FIELDS (TREE_TYPE (field));
|
||||
for (; uelt; uelt = TREE_CHAIN (uelt))
|
||||
{
|
||||
if (TREE_CODE (uelt) != FIELD_DECL)
|
||||
continue;
|
||||
|
||||
DECL_FIELD_CONTEXT (uelt) = DECL_FIELD_CONTEXT (field);
|
||||
DECL_FIELD_BITPOS (uelt) = DECL_FIELD_BITPOS (field);
|
||||
}
|
||||
|
@ -3552,6 +3616,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
tree uelt = TYPE_FIELDS (TREE_TYPE (field));
|
||||
for (; uelt; uelt = TREE_CHAIN (uelt))
|
||||
{
|
||||
if (TREE_CODE (uelt) != FIELD_DECL)
|
||||
continue;
|
||||
|
||||
DECL_FIELD_CONTEXT (uelt) = DECL_FIELD_CONTEXT (field);
|
||||
DECL_FIELD_BITPOS (uelt) = DECL_FIELD_BITPOS (field);
|
||||
}
|
||||
|
|
|
@ -2254,7 +2254,6 @@ extern tree copy_binfo PROTO((tree));
|
|||
extern tree binfo_value PROTO((tree, tree));
|
||||
extern tree reverse_path PROTO((tree));
|
||||
extern tree virtual_member PROTO((tree, tree));
|
||||
extern tree virtual_offset PROTO((tree, tree, tree));
|
||||
extern void debug_binfo PROTO((tree));
|
||||
extern int decl_list_length PROTO((tree));
|
||||
extern int count_functions PROTO((tree));
|
||||
|
|
23
gcc/cp/cvt.c
23
gcc/cp/cvt.c
|
@ -425,10 +425,11 @@ build_up_reference (type, arg, flags, checkconst)
|
|||
break;
|
||||
|
||||
case PARM_DECL:
|
||||
#if 0
|
||||
if (targ == current_class_decl)
|
||||
{
|
||||
error ("address of `this' not available");
|
||||
#if 0
|
||||
/* #if 0 */
|
||||
/* This code makes the following core dump the compiler on a sun4,
|
||||
if the code below is used.
|
||||
|
||||
|
@ -465,16 +466,18 @@ build_up_reference (type, arg, flags, checkconst)
|
|||
TREE_ADDRESSABLE (targ) = 1; /* so compiler doesn't die later */
|
||||
put_var_into_stack (targ);
|
||||
break;
|
||||
#else
|
||||
/* #else */
|
||||
return error_mark_node;
|
||||
#endif
|
||||
/* #endif */
|
||||
}
|
||||
#endif
|
||||
/* Fall through. */
|
||||
case VAR_DECL:
|
||||
case CONST_DECL:
|
||||
if (DECL_REGISTER (targ) && !TREE_ADDRESSABLE (targ))
|
||||
warning ("address needed to build reference for `%s', which is declared `register'",
|
||||
IDENTIFIER_POINTER (DECL_NAME (targ)));
|
||||
if (DECL_REGISTER (targ) && !TREE_ADDRESSABLE (targ)
|
||||
&& !DECL_ARTIFICIAL (targ))
|
||||
cp_warning ("address needed to build reference for `%D', which is declared `register'",
|
||||
targ);
|
||||
else if (staticp (targ))
|
||||
literal_flag = 1;
|
||||
|
||||
|
@ -1206,6 +1209,9 @@ cp_convert (type, expr, convtype, flags)
|
|||
else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
|
||||
e = convert_from_reference (e);
|
||||
|
||||
if (TREE_CODE (e) == OFFSET_REF)
|
||||
e = resolve_offset_ref (e);
|
||||
|
||||
if (TREE_READONLY_DECL_P (e))
|
||||
e = decl_constant_value (e);
|
||||
|
||||
|
@ -1223,10 +1229,7 @@ cp_convert (type, expr, convtype, flags)
|
|||
if (flag_pedantic_errors)
|
||||
return error_mark_node;
|
||||
}
|
||||
if (form == OFFSET_TYPE)
|
||||
cp_error_at ("pointer-to-member expression object not composed with type `%D' object",
|
||||
TYPE_NAME (TYPE_OFFSET_BASETYPE (intype)));
|
||||
else if (IS_AGGR_TYPE (intype))
|
||||
if (IS_AGGR_TYPE (intype))
|
||||
{
|
||||
tree rval;
|
||||
rval = build_type_conversion (CONVERT_EXPR, type, e, 1);
|
||||
|
|
|
@ -7091,7 +7091,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
dname = decl;
|
||||
decl = NULL_TREE;
|
||||
|
||||
if (IDENTIFIER_OPNAME_P (dname))
|
||||
if (! IDENTIFIER_OPNAME_P (dname)
|
||||
/* Linux headers use '__op'. Arrgh. */
|
||||
|| IDENTIFIER_TYPENAME_P (dname) && ! TREE_TYPE (dname))
|
||||
name = IDENTIFIER_POINTER (dname);
|
||||
else
|
||||
{
|
||||
if (IDENTIFIER_TYPENAME_P (dname))
|
||||
{
|
||||
|
@ -7102,8 +7106,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
}
|
||||
name = operator_name_string (dname);
|
||||
}
|
||||
else
|
||||
name = IDENTIFIER_POINTER (dname);
|
||||
break;
|
||||
|
||||
case RECORD_TYPE:
|
||||
|
@ -7688,17 +7690,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
break;
|
||||
}
|
||||
|
||||
if (scanner == IDENTIFIER_AS_LIST (ridpointers [(int) RID_TYPEDEF]))
|
||||
{
|
||||
if (previous_declspec)
|
||||
TREE_CHAIN (previous_declspec)
|
||||
= IDENTIFIER_AS_LIST (ridpointers [(int) RID_STATIC]);
|
||||
else
|
||||
declspecs
|
||||
= IDENTIFIER_AS_LIST (ridpointers [(int) RID_STATIC]);
|
||||
}
|
||||
if (previous_declspec)
|
||||
TREE_CHAIN (previous_declspec) = TREE_CHAIN (scanner);
|
||||
else
|
||||
TREE_VALUE (scanner) = ridpointers[(int) RID_STATIC];
|
||||
declspecs = TREE_CHAIN (scanner);
|
||||
|
||||
declspecs = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
|
||||
declspecs);
|
||||
|
||||
/* In the recursive call to grokdeclarator we need to know
|
||||
whether we are working on a signature-local typedef. */
|
||||
|
@ -7707,6 +7705,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
|
||||
loc_typedecl =
|
||||
grokdeclarator (declarator, declspecs, FIELD, 0, NULL_TREE);
|
||||
|
||||
if (previous_declspec)
|
||||
TREE_CHAIN (previous_declspec) = scanner;
|
||||
|
||||
if (loc_typedecl != error_mark_node)
|
||||
{
|
||||
|
@ -7714,6 +7715,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
register int *pi;
|
||||
|
||||
TREE_SET_CODE (loc_typedecl, TYPE_DECL);
|
||||
/* This is the same field as DECL_ARGUMENTS, which is set for
|
||||
function typedefs by the above grokdeclarator. */
|
||||
DECL_NESTED_TYPENAME (loc_typedecl) = 0;
|
||||
|
||||
pi = (int *) permalloc (sizeof (struct lang_decl_flags));
|
||||
while (i > 0)
|
||||
|
@ -11529,20 +11533,19 @@ finish_function (lineno, call_poplevel)
|
|||
/* So we can tell if jump_optimize sets it to 1. */
|
||||
can_reach_end = 0;
|
||||
|
||||
/* ??? Compensate for Sun brain damage in dealing with data segments
|
||||
of PIC code. */
|
||||
if (flag_pic
|
||||
&& (DECL_CONSTRUCTOR_P (fndecl)
|
||||
|| DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
|
||||
&& CLASSTYPE_NEEDS_VIRTUAL_REINIT (TYPE_METHOD_BASETYPE (fntype)))
|
||||
DECL_INLINE (fndecl) = 0;
|
||||
|
||||
if (DECL_EXTERNAL (fndecl)
|
||||
/* This function is just along for the ride. If we can make
|
||||
it inline, that's great. Otherwise, just punt it. */
|
||||
&& (DECL_INLINE (fndecl) == 0
|
||||
|| flag_no_inline
|
||||
|| function_cannot_inline_p (fndecl)))
|
||||
|| function_cannot_inline_p (fndecl)
|
||||
/* ??? Compensate for Sun brain damage in dealing with
|
||||
data segments of PIC code. */
|
||||
|| (flag_pic
|
||||
&& (DECL_CONSTRUCTOR_P (fndecl)
|
||||
|| DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
|
||||
&& CLASSTYPE_NEEDS_VIRTUAL_REINIT (TYPE_METHOD_BASETYPE (fntype)))))
|
||||
|
||||
{
|
||||
extern int rtl_dump_and_exit;
|
||||
int old_rtl_dump_and_exit = rtl_dump_and_exit;
|
||||
|
|
|
@ -2100,8 +2100,16 @@ finish_anon_union (anon_union_decl)
|
|||
}
|
||||
if (static_p)
|
||||
{
|
||||
make_decl_rtl (main_decl, 0, global_bindings_p ());
|
||||
DECL_RTL (anon_union_decl) = DECL_RTL (main_decl);
|
||||
if (main_decl)
|
||||
{
|
||||
make_decl_rtl (main_decl, 0, global_bindings_p ());
|
||||
DECL_RTL (anon_union_decl) = DECL_RTL (main_decl);
|
||||
}
|
||||
else
|
||||
{
|
||||
warning ("anonymous union with no members");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* The following call assumes that there are never any cleanups
|
||||
|
@ -2712,7 +2720,6 @@ finish_file ()
|
|||
}
|
||||
}
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (decl))
|
||||
|| init == 0
|
||||
|| TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
|
||||
expand_aggr_init (decl, init, 0);
|
||||
else if (TREE_CODE (init) == TREE_VEC)
|
||||
|
|
|
@ -671,13 +671,22 @@ dump_decl (t, v)
|
|||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tree arg = TREE_VEC_ELT (args, i);
|
||||
if (TREE_CODE (arg) == IDENTIFIER_NODE)
|
||||
tree defval = TREE_PURPOSE (arg);
|
||||
arg = TREE_VALUE (arg);
|
||||
if (TREE_CODE (arg) == TYPE_DECL)
|
||||
{
|
||||
OB_PUTS ("class ");
|
||||
OB_PUTID (arg);
|
||||
OB_PUTID (DECL_NAME (arg));
|
||||
}
|
||||
else
|
||||
dump_decl (arg, 1);
|
||||
|
||||
if (defval)
|
||||
{
|
||||
OB_PUTS (" = ");
|
||||
dump_decl (defval, 1);
|
||||
}
|
||||
|
||||
OB_PUTC2 (',', ' ');
|
||||
}
|
||||
OB_UNPUT (2);
|
||||
|
|
|
@ -1392,7 +1392,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
|
|||
separately from the object being initialized. */
|
||||
if (TREE_CODE (init) == TARGET_EXPR)
|
||||
{
|
||||
if (init_type == type)
|
||||
if (TYPE_MAIN_VARIANT (init_type) == TYPE_MAIN_VARIANT (type))
|
||||
{
|
||||
if (TREE_CODE (exp) == VAR_DECL
|
||||
|| TREE_CODE (exp) == RESULT_DECL)
|
||||
|
|
|
@ -2875,7 +2875,7 @@ linenum:
|
|||
if (c_header_level && --c_header_level == 0)
|
||||
{
|
||||
if (entering_c_header)
|
||||
warning ("Badly nested C headers from preprocessor");
|
||||
warning ("badly nested C headers from preprocessor");
|
||||
--pending_lang_change;
|
||||
}
|
||||
if (flag_cadillac)
|
||||
|
|
|
@ -463,9 +463,9 @@ build_overload_identifier (name)
|
|||
icat (nparms);
|
||||
for (i = 0; i < nparms; i++)
|
||||
{
|
||||
tree parm = TREE_VEC_ELT (parmlist, i);
|
||||
tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));
|
||||
tree arg = TREE_VEC_ELT (arglist, i);
|
||||
if (TREE_CODE (parm) == IDENTIFIER_NODE)
|
||||
if (TREE_CODE (parm) == TYPE_DECL)
|
||||
{
|
||||
/* This parameter is a type. */
|
||||
OB_PUTC ('Z');
|
||||
|
|
|
@ -221,7 +221,7 @@ empty_parms ()
|
|||
%type <ttype> type_id absdcl type_quals
|
||||
%type <ttype> direct_abstract_declarator conversion_declarator
|
||||
%type <ttype> new_type_id new_declarator direct_new_declarator
|
||||
%type <ttype> xexpr parmlist parms parm bad_parm
|
||||
%type <ttype> xexpr parmlist parms parm bad_parm full_parm
|
||||
%type <ttype> identifiers_or_typenames
|
||||
%type <ttype> fcast_or_absdcl regcast_or_absdcl sub_cast_expr
|
||||
%type <ttype> expr_or_declarator complex_notype_declarator
|
||||
|
@ -250,6 +250,7 @@ empty_parms ()
|
|||
%type <ttype> nonmomentary_expr
|
||||
%type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
|
||||
%type <ttype> template_header template_parm_list template_parm
|
||||
%type <ttype> template_type_parm
|
||||
%type <ttype> template_type template_arg_list template_arg
|
||||
%type <ttype> template_instantiation template_type_name tmpl.2
|
||||
%type <ttype> template_instantiate_once template_instantiate_some
|
||||
|
@ -373,6 +374,20 @@ template_parm_list:
|
|||
{ $$ = process_template_parm ($1, $3); }
|
||||
;
|
||||
|
||||
template_type_parm:
|
||||
aggr
|
||||
{
|
||||
$$ = build_tree_list ($1, NULL_TREE);
|
||||
ttpa:
|
||||
if (TREE_PURPOSE ($$) == signature_type_node)
|
||||
sorry ("signature as template type parameter");
|
||||
else if (TREE_PURPOSE ($$) != class_type_node)
|
||||
pedwarn ("template type parameters must use the keyword `class'");
|
||||
}
|
||||
| aggr identifier
|
||||
{ $$ = build_tree_list ($1, $2); goto ttpa; }
|
||||
;
|
||||
|
||||
template_parm:
|
||||
/* The following rules introduce a new reduce/reduce
|
||||
conflict on the ',' and '>' input tokens: they are valid
|
||||
|
@ -381,24 +396,11 @@ template_parm:
|
|||
By putting them before the `parm' rule, we get
|
||||
their match before considering them nameless parameter
|
||||
declarations. */
|
||||
aggr identifier
|
||||
{
|
||||
if ($1 == signature_type_node)
|
||||
sorry ("signature as template type parameter");
|
||||
else if ($1 != class_type_node)
|
||||
error ("template type parameter must use keyword `class'");
|
||||
$$ = build_tree_list ($2, NULL_TREE);
|
||||
}
|
||||
| aggr identifier_defn ':' base_class.1
|
||||
{
|
||||
if ($1 == signature_type_node)
|
||||
sorry ("signature as template type parameter");
|
||||
else if ($1 != class_type_node)
|
||||
error ("template type parameter must use keyword `class'");
|
||||
warning ("restricted template type parameters not yet implemented");
|
||||
$$ = build_tree_list ($2, $4);
|
||||
}
|
||||
| parm
|
||||
template_type_parm
|
||||
{ $$ = build_tree_list (NULL_TREE, $$); }
|
||||
| template_type_parm '=' typespec
|
||||
{ $$ = build_tree_list ($3, $$); }
|
||||
| full_parm
|
||||
;
|
||||
|
||||
overloaddef:
|
||||
|
@ -782,6 +784,8 @@ template_type:
|
|||
template_type_name:
|
||||
PTYPENAME '<' template_arg_list '>'
|
||||
{ $$ = lookup_template_class ($$, $3, NULL_TREE); }
|
||||
| PTYPENAME '<' '>'
|
||||
{ $$ = lookup_template_class ($$, NULL_TREE, NULL_TREE); }
|
||||
| TYPENAME '<' template_arg_list '>'
|
||||
{ $$ = lookup_template_class ($$, $3, NULL_TREE); }
|
||||
;
|
||||
|
@ -3550,10 +3554,8 @@ parms:
|
|||
{ $$ = build_tree_list (NULL_TREE, $$); }
|
||||
| parm '=' init
|
||||
{ $$ = build_tree_list ($3, $$); }
|
||||
| parms_comma parm
|
||||
{ $$ = chainon ($$, build_tree_list (NULL_TREE, $2)); }
|
||||
| parms_comma parm '=' init
|
||||
{ $$ = chainon ($$, build_tree_list ($4, $2)); }
|
||||
| parms_comma full_parm
|
||||
{ $$ = chainon ($$, $2); }
|
||||
| parms_comma bad_parm
|
||||
{ $$ = chainon ($$, build_tree_list (NULL_TREE, $2)); }
|
||||
| parms_comma bad_parm '=' init
|
||||
|
@ -3599,6 +3601,13 @@ named_parm:
|
|||
{ $$ = build_tree_list ($$, $2); }
|
||||
;
|
||||
|
||||
full_parm:
|
||||
parm
|
||||
{ $$ = build_tree_list (NULL_TREE, $$); }
|
||||
| parm '=' init
|
||||
{ $$ = build_tree_list ($3, $$); }
|
||||
;
|
||||
|
||||
parm:
|
||||
named_parm
|
||||
| type_id
|
||||
|
|
169
gcc/cp/pt.c
169
gcc/cp/pt.c
|
@ -81,18 +81,19 @@ process_template_parm (list, next)
|
|||
{
|
||||
tree parm;
|
||||
tree decl = 0;
|
||||
tree defval;
|
||||
int is_type;
|
||||
parm = next;
|
||||
my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259);
|
||||
is_type = TREE_CODE (TREE_PURPOSE (parm)) == IDENTIFIER_NODE;
|
||||
defval = TREE_PURPOSE (parm);
|
||||
parm = TREE_VALUE (parm);
|
||||
is_type = TREE_PURPOSE (parm) == class_type_node;
|
||||
if (!is_type)
|
||||
{
|
||||
tree tinfo = 0;
|
||||
parm = TREE_PURPOSE (parm);
|
||||
my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 260);
|
||||
parm = TREE_VALUE (parm);
|
||||
my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260);
|
||||
/* is a const-param */
|
||||
parm = grokdeclarator (TREE_VALUE (next), TREE_PURPOSE (next),
|
||||
parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm),
|
||||
PARM, 0, NULL_TREE);
|
||||
/* A template parameter is not modifiable. */
|
||||
TREE_READONLY (parm) = 1;
|
||||
|
@ -117,11 +118,19 @@ process_template_parm (list, next)
|
|||
else
|
||||
{
|
||||
tree t = make_node (TEMPLATE_TYPE_PARM);
|
||||
decl = build_decl (TYPE_DECL, TREE_PURPOSE (parm), t);
|
||||
TYPE_NAME (t) = decl;
|
||||
TREE_VALUE (parm) = t;
|
||||
decl = build_decl (TYPE_DECL, TREE_VALUE (parm), t);
|
||||
TYPE_MAIN_DECL (t) = decl;
|
||||
parm = decl;
|
||||
if (defval)
|
||||
{
|
||||
if (IDENTIFIER_HAS_TYPE_VALUE (defval))
|
||||
defval = IDENTIFIER_TYPE_VALUE (defval);
|
||||
else
|
||||
defval = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (defval));
|
||||
}
|
||||
}
|
||||
pushdecl (decl);
|
||||
parm = build_tree_list (defval, parm);
|
||||
return chainon (list, parm);
|
||||
}
|
||||
|
||||
|
@ -135,6 +144,7 @@ end_template_parm_list (parms)
|
|||
tree parms;
|
||||
{
|
||||
int nparms = 0;
|
||||
int saw_default = 0;
|
||||
tree saved_parmlist;
|
||||
tree parm;
|
||||
for (parm = parms; parm; parm = TREE_CHAIN (parm))
|
||||
|
@ -143,13 +153,19 @@ end_template_parm_list (parms)
|
|||
|
||||
for (parm = parms, nparms = 0; parm; parm = TREE_CHAIN (parm), nparms++)
|
||||
{
|
||||
tree p = parm;
|
||||
if (TREE_CODE (p) == TREE_LIST)
|
||||
tree p = TREE_VALUE (parm);
|
||||
if (TREE_PURPOSE (parm))
|
||||
saw_default = 1;
|
||||
else if (saw_default)
|
||||
{
|
||||
tree t = TREE_VALUE (p);
|
||||
TREE_VALUE (p) = NULL_TREE;
|
||||
p = TREE_PURPOSE (p);
|
||||
my_friendly_assert (TREE_CODE (p) == IDENTIFIER_NODE, 261);
|
||||
error ("if a default argument is given for one template parameter");
|
||||
error ("default arguments must be given for all subsequent");
|
||||
error ("parameters as well");
|
||||
}
|
||||
|
||||
if (TREE_CODE (p) == TYPE_DECL)
|
||||
{
|
||||
tree t = TREE_TYPE (p);
|
||||
TEMPLATE_TYPE_SET_INFO (t, saved_parmlist, nparms);
|
||||
}
|
||||
else
|
||||
|
@ -158,7 +174,7 @@ end_template_parm_list (parms)
|
|||
DECL_INITIAL (p) = NULL_TREE;
|
||||
TEMPLATE_CONST_SET_INFO (tinfo, saved_parmlist, nparms);
|
||||
}
|
||||
TREE_VEC_ELT (saved_parmlist, nparms) = p;
|
||||
TREE_VEC_ELT (saved_parmlist, nparms) = parm;
|
||||
}
|
||||
set_current_level_tags_transparency (1);
|
||||
processing_template_decl++;
|
||||
|
@ -354,47 +370,63 @@ coerce_template_parms (parms, arglist, in_decl)
|
|||
tree parms, arglist;
|
||||
tree in_decl;
|
||||
{
|
||||
int nparms, i, lost = 0;
|
||||
int nparms, nargs, i, lost = 0;
|
||||
tree vec;
|
||||
|
||||
if (TREE_CODE (arglist) == TREE_VEC)
|
||||
nparms = TREE_VEC_LENGTH (arglist);
|
||||
if (arglist == NULL_TREE)
|
||||
nargs = 0;
|
||||
else if (TREE_CODE (arglist) == TREE_VEC)
|
||||
nargs = TREE_VEC_LENGTH (arglist);
|
||||
else
|
||||
nparms = list_length (arglist);
|
||||
if (nparms != TREE_VEC_LENGTH (parms))
|
||||
nargs = list_length (arglist);
|
||||
|
||||
nparms = TREE_VEC_LENGTH (parms);
|
||||
|
||||
if (nargs > nparms
|
||||
|| (nargs < nparms
|
||||
&& TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)) == NULL_TREE))
|
||||
{
|
||||
error ("incorrect number of parameters (%d, should be %d)",
|
||||
nparms, TREE_VEC_LENGTH (parms));
|
||||
nargs, nparms);
|
||||
if (in_decl)
|
||||
cp_error_at ("in template expansion for decl `%D'", in_decl);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (TREE_CODE (arglist) == TREE_VEC)
|
||||
if (arglist && TREE_CODE (arglist) == TREE_VEC)
|
||||
vec = copy_node (arglist);
|
||||
else
|
||||
{
|
||||
vec = make_tree_vec (nparms);
|
||||
for (i = 0; i < nparms; i++)
|
||||
{
|
||||
tree arg = arglist;
|
||||
arglist = TREE_CHAIN (arglist);
|
||||
if (arg == error_mark_node)
|
||||
lost++;
|
||||
tree arg;
|
||||
|
||||
if (arglist)
|
||||
{
|
||||
arg = arglist;
|
||||
arglist = TREE_CHAIN (arglist);
|
||||
|
||||
if (arg == error_mark_node)
|
||||
lost++;
|
||||
else
|
||||
arg = TREE_VALUE (arg);
|
||||
}
|
||||
else
|
||||
arg = TREE_VALUE (arg);
|
||||
arg = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
|
||||
|
||||
TREE_VEC_ELT (vec, i) = arg;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < nparms; i++)
|
||||
{
|
||||
tree arg = TREE_VEC_ELT (vec, i);
|
||||
tree parm = TREE_VEC_ELT (parms, i);
|
||||
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
|
||||
tree val = 0;
|
||||
int is_type, requires_type;
|
||||
|
||||
is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't';
|
||||
requires_type = TREE_CODE (parm) == IDENTIFIER_NODE;
|
||||
requires_type = TREE_CODE (parm) == TYPE_DECL;
|
||||
if (is_type != requires_type)
|
||||
{
|
||||
if (in_decl)
|
||||
|
@ -415,7 +447,7 @@ coerce_template_parms (parms, arglist, in_decl)
|
|||
{
|
||||
grok_template_type (vec, &TREE_TYPE (parm));
|
||||
val = digest_init (TREE_TYPE (parm), arg, (tree *) 0);
|
||||
|
||||
|
||||
if (val == error_mark_node)
|
||||
;
|
||||
|
||||
|
@ -489,12 +521,13 @@ mangle_class_name_for_template (name, parms, arglist)
|
|||
my_friendly_assert (nparms == TREE_VEC_LENGTH (arglist), 268);
|
||||
for (i = 0; i < nparms; i++)
|
||||
{
|
||||
tree parm = TREE_VEC_ELT (parms, i), arg = TREE_VEC_ELT (arglist, i);
|
||||
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
|
||||
tree arg = TREE_VEC_ELT (arglist, i);
|
||||
|
||||
if (i)
|
||||
ccat (',');
|
||||
|
||||
if (TREE_CODE (parm) == IDENTIFIER_NODE)
|
||||
if (TREE_CODE (parm) == TYPE_DECL)
|
||||
{
|
||||
cat (type_as_string (arg, 0));
|
||||
continue;
|
||||
|
@ -573,7 +606,7 @@ lookup_template_class (d1, arglist, in_decl)
|
|||
}
|
||||
parmlist = DECL_TEMPLATE_PARMS (template);
|
||||
|
||||
arglist = coerce_template_parms (parmlist, arglist, in_decl);
|
||||
arglist = coerce_template_parms (parmlist, arglist, template);
|
||||
if (arglist == error_mark_node)
|
||||
return error_mark_node;
|
||||
if (uses_template_parms (arglist))
|
||||
|
@ -619,11 +652,11 @@ push_template_decls (parmlist, arglist, class_level)
|
|||
for (i = 0; i < nparms; i++)
|
||||
{
|
||||
int requires_type, is_type;
|
||||
tree parm = TREE_VEC_ELT (parmlist, i);
|
||||
tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));
|
||||
tree arg = TREE_VEC_ELT (arglist, i);
|
||||
tree decl = 0;
|
||||
|
||||
requires_type = TREE_CODE (parm) == IDENTIFIER_NODE;
|
||||
requires_type = TREE_CODE (parm) == TYPE_DECL;
|
||||
is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't';
|
||||
if (is_type)
|
||||
{
|
||||
|
@ -635,7 +668,7 @@ push_template_decls (parmlist, arglist, class_level)
|
|||
}
|
||||
decl = arg;
|
||||
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 't', 273);
|
||||
decl = build_decl (TYPE_DECL, parm, decl);
|
||||
decl = build_decl (TYPE_DECL, DECL_NAME (parm), decl);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -878,9 +911,8 @@ instantiate_member_templates (classname)
|
|||
case 1:
|
||||
/* Failure. */
|
||||
failure:
|
||||
cp_error ("type unification error instantiating %T::%D",
|
||||
classname, tdecl);
|
||||
cp_error_at ("for template declaration `%D'", tdecl);
|
||||
cp_error_at ("type unification error instantiating `%D'", tdecl);
|
||||
cp_error ("while instantiating members of `%T'", classname);
|
||||
|
||||
continue /* loop of members */;
|
||||
default:
|
||||
|
@ -1781,6 +1813,7 @@ overload_template_name (id, classlevel)
|
|||
|| TREE_CODE (t) == UNINSTANTIATED_P_TYPE, 286);
|
||||
|
||||
decl = build_decl (TYPE_DECL, template, t);
|
||||
SET_DECL_ARTIFICIAL (decl);
|
||||
|
||||
#if 0 /* fix this later */
|
||||
/* We don't want to call here if the work has already been done. */
|
||||
|
@ -2035,22 +2068,20 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
|
|||
return 1;
|
||||
}
|
||||
idx = TEMPLATE_TYPE_IDX (parm);
|
||||
/* Template type parameters cannot contain cv-quals; i.e.
|
||||
template <class T> void f (T& a, T& b) will not generate
|
||||
void f (const int& a, const int& b). */
|
||||
if (TYPE_READONLY (arg) > TYPE_READONLY (parm)
|
||||
|| TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm))
|
||||
return 1;
|
||||
arg = TYPE_MAIN_VARIANT (arg);
|
||||
/* Simple cases: Value already set, does match or doesn't. */
|
||||
if (targs[idx] == arg)
|
||||
return 0;
|
||||
else if (targs[idx])
|
||||
{
|
||||
if (TYPE_MAIN_VARIANT (targs[idx]) == TYPE_MAIN_VARIANT (arg))
|
||||
/* allow different parms to have different cv-qualifiers */;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
/* Check for mixed types and values. */
|
||||
if (TREE_CODE (TREE_VEC_ELT (tparms, idx)) != IDENTIFIER_NODE)
|
||||
return 1;
|
||||
/* Allow trivial conversions. */
|
||||
if (TYPE_READONLY (parm) < TYPE_READONLY (arg)
|
||||
|| TYPE_VOLATILE (parm) < TYPE_VOLATILE (arg))
|
||||
/* Check for mixed types and values. */
|
||||
if (TREE_CODE (TREE_VALUE (TREE_VEC_ELT (tparms, idx))) != TYPE_DECL)
|
||||
return 1;
|
||||
targs[idx] = arg;
|
||||
return 0;
|
||||
|
@ -2399,12 +2430,11 @@ do_type_instantiation (name, storage)
|
|||
tree t = TREE_TYPE (name);
|
||||
int extern_p;
|
||||
|
||||
/* With -fexternal-templates, explicit instantiations are treated the same
|
||||
as implicit ones. */
|
||||
if (flag_external_templates)
|
||||
return;
|
||||
|
||||
if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t))
|
||||
return;
|
||||
|
||||
if (TYPE_SIZE (t) == NULL_TREE)
|
||||
{
|
||||
cp_error ("explicit instantiation of `%#T' before definition of template",
|
||||
|
@ -2423,6 +2453,14 @@ do_type_instantiation (name, storage)
|
|||
extern_p = 0;
|
||||
}
|
||||
|
||||
/* We've already instantiated this. */
|
||||
if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t))
|
||||
{
|
||||
if (! extern_p)
|
||||
cp_pedwarn ("multiple explicit instantiation of `%#T'", t);
|
||||
return;
|
||||
}
|
||||
|
||||
SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
|
||||
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p;
|
||||
SET_CLASSTYPE_INTERFACE_KNOWN (t);
|
||||
|
@ -2436,17 +2474,26 @@ do_type_instantiation (name, storage)
|
|||
|
||||
/* 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))
|
||||
tree tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
|
||||
for (; tmp; tmp = TREE_CHAIN (tmp))
|
||||
{
|
||||
SET_DECL_EXPLICIT_INSTANTIATION (method);
|
||||
TREE_PUBLIC (method) = 1;
|
||||
DECL_EXTERNAL (method)
|
||||
= (extern_p || (DECL_INLINE (method) && ! flag_implement_inlines));
|
||||
SET_DECL_EXPLICIT_INSTANTIATION (tmp);
|
||||
TREE_PUBLIC (tmp) = 1;
|
||||
DECL_EXTERNAL (tmp)
|
||||
= (extern_p || (DECL_INLINE (tmp) && ! flag_implement_inlines));
|
||||
}
|
||||
}
|
||||
|
||||
/* and data member templates, too */
|
||||
#if 0
|
||||
for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
|
||||
{
|
||||
if (TREE_CODE (tmp) == VAR_DECL)
|
||||
/* eventually do something */;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp))
|
||||
do_type_instantiation (TREE_VALUE (tmp), storage);
|
||||
}
|
||||
}
|
||||
|
||||
tree
|
||||
|
|
|
@ -1913,6 +1913,10 @@ get_matching_virtual (binfo, fndecl, dtorp)
|
|||
if (IDENTIFIER_VIRTUAL_P (declarator) == 0)
|
||||
return NULL_TREE;
|
||||
|
||||
baselink = get_virtuals_named_this (binfo);
|
||||
if (baselink == NULL_TREE)
|
||||
return NULL_TREE;
|
||||
|
||||
drettype = TREE_TYPE (TREE_TYPE (fndecl));
|
||||
dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
if (DECL_STATIC_FUNCTION_P (fndecl))
|
||||
|
@ -1920,8 +1924,7 @@ get_matching_virtual (binfo, fndecl, dtorp)
|
|||
else
|
||||
instptr_type = TREE_TYPE (TREE_VALUE (dtypes));
|
||||
|
||||
for (baselink = get_virtuals_named_this (binfo);
|
||||
baselink; baselink = next_baselink (baselink))
|
||||
for (; baselink; baselink = next_baselink (baselink))
|
||||
{
|
||||
for (tmp = TREE_VALUE (baselink); tmp; tmp = DECL_CHAIN (tmp))
|
||||
{
|
||||
|
@ -1945,7 +1948,7 @@ get_matching_virtual (binfo, fndecl, dtorp)
|
|||
&& ! comptypes (TREE_TYPE (TREE_TYPE (tmp)), drettype, 1))
|
||||
{
|
||||
cp_error ("conflicting return type specified for virtual function `%#D'", fndecl);
|
||||
cp_error ("overriding definition as `%#D'", tmp);
|
||||
cp_error_at ("overriding definition as `%#D'", tmp);
|
||||
SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
|
||||
}
|
||||
break;
|
||||
|
@ -2697,13 +2700,22 @@ free_mi_matrix ()
|
|||
/* If we want debug info for a type TYPE, make sure all its base types
|
||||
are also marked as being potentially interesting. This avoids
|
||||
the problem of not writing any debug info for intermediate basetypes
|
||||
that have abstract virtual functions. */
|
||||
that have abstract virtual functions. Also mark member types. */
|
||||
|
||||
void
|
||||
note_debug_info_needed (type)
|
||||
tree type;
|
||||
{
|
||||
tree field;
|
||||
dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp);
|
||||
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
|
||||
{
|
||||
tree ttype;
|
||||
if (TREE_CODE (field) == FIELD_DECL
|
||||
&& IS_AGGR_TYPE (ttype = target_type (TREE_TYPE (field)))
|
||||
&& dfs_debug_unmarkedp (TYPE_BINFO (ttype)))
|
||||
note_debug_info_needed (ttype);
|
||||
}
|
||||
}
|
||||
|
||||
/* Subroutines of push_class_decls (). */
|
||||
|
|
151
gcc/cp/tree.c
151
gcc/cp/tree.c
|
@ -35,66 +35,75 @@ int
|
|||
lvalue_p (ref)
|
||||
tree ref;
|
||||
{
|
||||
register enum tree_code code = TREE_CODE (ref);
|
||||
if (! language_lvalue_valid (ref))
|
||||
return 0;
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
|
||||
return 1;
|
||||
|
||||
if (language_lvalue_valid (ref))
|
||||
if (ref == current_class_decl && flag_this_is_variable <= 0)
|
||||
return 0;
|
||||
|
||||
switch (TREE_CODE (ref))
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
|
||||
/* preincrements and predecrements are valid lvals, provided
|
||||
what they refer to are valid lvals. */
|
||||
case PREINCREMENT_EXPR:
|
||||
case PREDECREMENT_EXPR:
|
||||
case COMPONENT_REF:
|
||||
case SAVE_EXPR:
|
||||
return lvalue_p (TREE_OPERAND (ref, 0));
|
||||
|
||||
case STRING_CST:
|
||||
return 1;
|
||||
|
||||
case VAR_DECL:
|
||||
if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
|
||||
&& DECL_LANG_SPECIFIC (ref)
|
||||
&& DECL_IN_AGGR_P (ref))
|
||||
return 0;
|
||||
case INDIRECT_REF:
|
||||
case ARRAY_REF:
|
||||
case PARM_DECL:
|
||||
case RESULT_DECL:
|
||||
case ERROR_MARK:
|
||||
if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
|
||||
return 1;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
/* preincrements and predecrements are valid lvals, provided
|
||||
what they refer to are valid lvals. */
|
||||
case PREINCREMENT_EXPR:
|
||||
case PREDECREMENT_EXPR:
|
||||
case COMPONENT_REF:
|
||||
case SAVE_EXPR:
|
||||
return lvalue_p (TREE_OPERAND (ref, 0));
|
||||
break;
|
||||
|
||||
case STRING_CST:
|
||||
return 1;
|
||||
case WITH_CLEANUP_EXPR:
|
||||
return lvalue_p (TREE_OPERAND (ref, 0));
|
||||
|
||||
case VAR_DECL:
|
||||
if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
|
||||
&& DECL_LANG_SPECIFIC (ref)
|
||||
&& DECL_IN_AGGR_P (ref))
|
||||
return 0;
|
||||
case INDIRECT_REF:
|
||||
case ARRAY_REF:
|
||||
case PARM_DECL:
|
||||
case RESULT_DECL:
|
||||
case ERROR_MARK:
|
||||
if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
|
||||
return 1;
|
||||
break;
|
||||
case TARGET_EXPR:
|
||||
return 1;
|
||||
|
||||
case TARGET_EXPR:
|
||||
case WITH_CLEANUP_EXPR:
|
||||
return 1;
|
||||
case CALL_EXPR:
|
||||
if (TREE_ADDRESSABLE (TREE_TYPE (ref)))
|
||||
return 1;
|
||||
break;
|
||||
|
||||
/* A currently unresolved scope ref. */
|
||||
case SCOPE_REF:
|
||||
my_friendly_abort (103);
|
||||
case OFFSET_REF:
|
||||
if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
|
||||
return 1;
|
||||
return lvalue_p (TREE_OPERAND (ref, 0))
|
||||
&& lvalue_p (TREE_OPERAND (ref, 1));
|
||||
break;
|
||||
/* A currently unresolved scope ref. */
|
||||
case SCOPE_REF:
|
||||
my_friendly_abort (103);
|
||||
case OFFSET_REF:
|
||||
if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
|
||||
return 1;
|
||||
return lvalue_p (TREE_OPERAND (ref, 0))
|
||||
&& lvalue_p (TREE_OPERAND (ref, 1));
|
||||
break;
|
||||
|
||||
case COND_EXPR:
|
||||
return (lvalue_p (TREE_OPERAND (ref, 1))
|
||||
&& lvalue_p (TREE_OPERAND (ref, 2)));
|
||||
case COND_EXPR:
|
||||
return (lvalue_p (TREE_OPERAND (ref, 1))
|
||||
&& lvalue_p (TREE_OPERAND (ref, 2)));
|
||||
|
||||
case MODIFY_EXPR:
|
||||
return 1;
|
||||
case MODIFY_EXPR:
|
||||
return 1;
|
||||
|
||||
case COMPOUND_EXPR:
|
||||
return lvalue_p (TREE_OPERAND (ref, 1));
|
||||
}
|
||||
case COMPOUND_EXPR:
|
||||
return lvalue_p (TREE_OPERAND (ref, 1));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1184,50 +1193,6 @@ virtual_member (elem, list)
|
|||
return rval;
|
||||
}
|
||||
|
||||
/* Return the offset (as an INTEGER_CST) for ELEM in LIST.
|
||||
INITIAL_OFFSET is the value to add to the offset that ELEM's
|
||||
binfo entry in LIST provides.
|
||||
|
||||
Returns NULL if ELEM does not have an binfo value in LIST. */
|
||||
|
||||
tree
|
||||
virtual_offset (elem, list, initial_offset)
|
||||
tree elem;
|
||||
tree list;
|
||||
tree initial_offset;
|
||||
{
|
||||
tree vb, offset;
|
||||
tree rval, nval;
|
||||
|
||||
for (vb = list; vb; vb = TREE_CHAIN (vb))
|
||||
if (elem == BINFO_TYPE (vb))
|
||||
return size_binop (PLUS_EXPR, initial_offset, BINFO_OFFSET (vb));
|
||||
rval = 0;
|
||||
for (vb = list; vb; vb = TREE_CHAIN (vb))
|
||||
{
|
||||
tree binfos = BINFO_BASETYPES (vb);
|
||||
int i;
|
||||
|
||||
if (binfos == NULL_TREE)
|
||||
continue;
|
||||
|
||||
for (i = TREE_VEC_LENGTH (binfos)-1; i >= 0; i--)
|
||||
{
|
||||
nval = binfo_value (elem, BINFO_TYPE (TREE_VEC_ELT (binfos, i)));
|
||||
if (nval)
|
||||
{
|
||||
if (rval && BINFO_OFFSET (nval) != BINFO_OFFSET (rval))
|
||||
my_friendly_abort (105);
|
||||
offset = BINFO_OFFSET (vb);
|
||||
rval = nval;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rval == NULL_TREE)
|
||||
return rval;
|
||||
return size_binop (PLUS_EXPR, offset, BINFO_OFFSET (rval));
|
||||
}
|
||||
|
||||
void
|
||||
debug_binfo (elem)
|
||||
tree elem;
|
||||
|
|
|
@ -1410,8 +1410,19 @@ tree
|
|||
build_object_ref (datum, basetype, field)
|
||||
tree datum, basetype, field;
|
||||
{
|
||||
tree dtype;
|
||||
if (datum == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
dtype = TREE_TYPE (datum);
|
||||
if (TREE_CODE (dtype) == REFERENCE_TYPE)
|
||||
dtype = TREE_TYPE (dtype);
|
||||
if (! IS_AGGR_TYPE_CODE (TREE_CODE (dtype)))
|
||||
{
|
||||
cp_error ("request for member `%T::%D' in expression of non-aggregate type `%T'",
|
||||
basetype, field, dtype);
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (basetype)))
|
||||
{
|
||||
warning ("signature name in scope resolution ignored");
|
||||
|
@ -3247,6 +3258,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
|
|||
case GE_EXPR:
|
||||
case LT_EXPR:
|
||||
case GT_EXPR:
|
||||
result_type = bool_type_node;
|
||||
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
|
||||
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
|
||||
short_compare = 1;
|
||||
|
@ -3295,7 +3307,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
|
|||
warning ("comparison between pointer and integer");
|
||||
op0 = convert (TREE_TYPE (op1), op0);
|
||||
}
|
||||
result_type = bool_type_node;
|
||||
else
|
||||
result_type = 0;
|
||||
converted = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -3717,7 +3730,7 @@ build_component_addr (arg, argtype, msg)
|
|||
}
|
||||
else
|
||||
/* This conversion is harmless. */
|
||||
rval = convert (argtype, rval);
|
||||
rval = convert_force (argtype, rval);
|
||||
|
||||
if (! integer_zerop (DECL_FIELD_BITPOS (field)))
|
||||
{
|
||||
|
@ -4939,7 +4952,7 @@ build_c_cast (type, expr)
|
|||
value = TREE_VALUE (value);
|
||||
|
||||
if (TREE_CODE (type) == VOID_TYPE)
|
||||
value = build1 (NOP_EXPR, type, value);
|
||||
value = build1 (CONVERT_EXPR, type, value);
|
||||
else if (TREE_TYPE (value) == NULL_TREE
|
||||
|| type_unknown_p (value))
|
||||
{
|
||||
|
@ -6445,7 +6458,8 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
|
|||
add_quals = 1;
|
||||
left_const &= TYPE_READONLY (ttl);
|
||||
|
||||
if (TREE_CODE (ttl) != POINTER_TYPE)
|
||||
if (TREE_CODE (ttl) != POINTER_TYPE
|
||||
|| TREE_CODE (ttr) != POINTER_TYPE)
|
||||
break;
|
||||
}
|
||||
unsigned_parity = TREE_UNSIGNED (ttl) - TREE_UNSIGNED (ttr);
|
||||
|
@ -7028,6 +7042,7 @@ c_expand_return (retval)
|
|||
&& TREE_CODE (TREE_OPERAND (retval, 0)) == TARGET_EXPR)
|
||||
retval = TREE_OPERAND (retval, 0);
|
||||
expand_aggr_init (result, retval, 0);
|
||||
expand_cleanups_to (NULL_TREE);
|
||||
DECL_INITIAL (result) = NULL_TREE;
|
||||
retval = 0;
|
||||
}
|
||||
|
@ -7046,6 +7061,7 @@ c_expand_return (retval)
|
|||
&& any_pending_cleanups (1))
|
||||
{
|
||||
retval = get_temp_regvar (valtype, retval);
|
||||
expand_cleanups_to (NULL_TREE);
|
||||
use_temp = obey_regdecls;
|
||||
result = 0;
|
||||
}
|
||||
|
@ -7071,7 +7087,10 @@ c_expand_return (retval)
|
|||
{
|
||||
/* Everything's great--RETVAL is in RESULT. */
|
||||
if (original_result_rtx)
|
||||
store_expr (result, original_result_rtx, 0);
|
||||
{
|
||||
store_expr (result, original_result_rtx, 0);
|
||||
expand_cleanups_to (NULL_TREE);
|
||||
}
|
||||
else if (retval && retval != result)
|
||||
{
|
||||
/* Clear this out so the later call to decl_function_context
|
||||
|
@ -7083,6 +7102,7 @@ c_expand_return (retval)
|
|||
RESULT from cleanups. */
|
||||
retval = build (INIT_EXPR, TREE_TYPE (result), result, retval);
|
||||
TREE_SIDE_EFFECTS (retval) = 1;
|
||||
retval = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (result), retval);
|
||||
expand_return (retval);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -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: 360. Free: */
|
||||
/* First used: 0 (reserved), Last used: 360. Free: 261. */
|
||||
|
||||
static int abortcount = 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue