Commit 72b7eeff by Mike Stump

76th Cygnus<->FSF merge

From-SVN: r10815
parent f82da7d2
......@@ -1658,6 +1658,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
/* We already know whether it's needed or not for vec delete. */
else if (name == ansi_opname[(int) VEC_DELETE_EXPR]
&& TYPE_LANG_SPECIFIC (TREE_TYPE (instance))
&& ! TYPE_VEC_DELETE_TAKES_SIZE (TREE_TYPE (instance)))
TREE_CHAIN (parms) = NULL_TREE;
......@@ -2464,17 +2465,13 @@ build_method_call (instance, name, parms, basetype_path, flags)
return build_signature_method_call (basetype, instance, function, parms);
function = DECL_MAIN_VARIANT (function);
/* Declare external function if necessary. */
assemble_external (function);
mark_used (function);
#if 1
/* Is it a synthesized method that needs to be synthesized? */
if (DECL_ARTIFICIAL (function) && ! flag_no_inline
&& ! DECL_INITIAL (function)
if (DECL_ARTIFICIAL (function) && ! DECL_INITIAL (function)
/* Kludge: don't synthesize for default args. */
&& current_function_decl)
synthesize_method (function);
#endif
if (pedantic && DECL_THIS_INLINE (function) && ! DECL_ARTIFICIAL (function)
&& ! DECL_INITIAL (function) && ! DECL_PENDING_INLINE_INFO (function))
......@@ -2670,7 +2667,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (TREE_CODE (function) == FUNCTION_DECL)
{
is_constructor = DECL_CONSTRUCTOR_P (function);
TREE_USED (function) = 1;
function = default_conversion (function);
}
else
......
......@@ -424,7 +424,6 @@ build_vfn_ref (ptr_to_instptr, instance, idx)
tree *ptr_to_instptr, instance;
tree idx;
{
extern int building_cleanup;
tree vtbl, aref;
tree basetype = TREE_TYPE (instance);
......@@ -481,7 +480,7 @@ build_vfn_ref (ptr_to_instptr, instance, idx)
/* Save the intermediate result in a SAVE_EXPR so we don't have to
compute each component of the virtual function pointer twice. */
if (!building_cleanup && TREE_CODE (aref) == INDIRECT_REF)
if (TREE_CODE (aref) == INDIRECT_REF)
TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
if (flag_vtable_thunks)
......@@ -1720,8 +1719,14 @@ finish_struct_bits (t, max_has_virtual)
/* If this type has a copy constructor, force its mode to be BLKmode, and
force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to
be passed by invisible reference and prevent it from being returned in
a register. */
if (! TYPE_HAS_TRIVIAL_INIT_REF (t))
a register.
Also do this if the class has BLKmode but can still be returned in
registers, since function_cannot_inline_p won't let us inline
functions returning such a type. This affects the HP-PA. */
if (! TYPE_HAS_TRIVIAL_INIT_REF (t)
|| (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t)
&& CLASSTYPE_NON_AGGREGATE (t)))
{
tree variants;
if (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
......@@ -1812,15 +1817,14 @@ grow_method (fn, method_vec_ptr)
us to reduce search time in places like `build_method_call' to
consider only reasonably likely functions. */
static tree
tree
finish_struct_methods (t, fn_fields, nonprivate_method)
tree t;
tree fn_fields;
int nonprivate_method;
{
tree method_vec;
tree save_fn_fields = tree_cons (NULL_TREE, NULL_TREE, fn_fields);
tree lastp;
tree save_fn_fields = fn_fields;
tree name = constructor_name (t);
int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
......@@ -1837,7 +1841,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
/* First fill in entry 0 with the constructors, and the next few with
type conversion operators (if any). */
for (lastp = save_fn_fields; fn_fields; fn_fields = TREE_CHAIN (lastp))
for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields))
{
tree fn_name = DECL_NAME (fn_fields);
if (fn_name == NULL_TREE)
......@@ -1887,26 +1891,17 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
grow_method (fn_fields, &method_vec);
}
else
{
lastp = fn_fields;
continue;
}
TREE_CHAIN (lastp) = TREE_CHAIN (fn_fields);
TREE_CHAIN (fn_fields) = NULL_TREE;
}
fn_fields = TREE_CHAIN (save_fn_fields);
while (fn_fields)
fn_fields = save_fn_fields;
for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields))
{
tree nextp;
tree fn_name = DECL_NAME (fn_fields);
if (fn_name == NULL_TREE)
fn_name = name;
nextp = TREE_CHAIN (fn_fields);
TREE_CHAIN (fn_fields) = NULL_TREE;
if (fn_name == name || IDENTIFIER_TYPENAME_P (fn_name))
continue;
if (fn_name == ansi_opname[(int) MODIFY_EXPR])
{
......@@ -1922,7 +1917,6 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
}
grow_method (fn_fields, &method_vec);
fn_fields = nextp;
}
TREE_VEC_LENGTH (method_vec) = (tree *)obstack_next_free (&class_obstack)
......@@ -2005,6 +1999,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
obstack_free (current_obstack, baselink_vec);
}
#if 0
/* Now add the methods to the TYPE_METHODS of T, arranged in a chain. */
{
tree x, last_x = NULL_TREE;
......@@ -2040,6 +2035,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
}
TYPE_METHODS (t) = method_vec;
#endif
return method_vec;
}
......@@ -2765,7 +2761,7 @@ finish_struct_1 (t, warn_anon)
tree name = TYPE_IDENTIFIER (t);
enum tree_code code = TREE_CODE (t);
tree fields = TYPE_FIELDS (t);
tree fn_fields = CLASSTYPE_METHODS (t);
tree fn_fields = TYPE_METHODS (t);
tree x, last_x, method_vec;
int needs_virtual_dtor;
int all_virtual;
......@@ -2920,7 +2916,7 @@ finish_struct_1 (t, warn_anon)
else
all_virtual = 0;
for (x = CLASSTYPE_METHODS (t); x; x = TREE_CHAIN (x))
for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
{
GNU_xref_member (current_class_name, x);
......@@ -3197,7 +3193,7 @@ finish_struct_1 (t, warn_anon)
{
tree type = TREE_TYPE (x);
if (TREE_CODE (type) == ARRAY_TYPE)
while (TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type);
if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x)
......@@ -3681,19 +3677,6 @@ finish_struct_1 (t, warn_anon)
}
}
}
/* Now fixup any virtual function entries from virtual bases
that have different deltas. */
vbases = CLASSTYPE_VBASECLASSES (t);
while (vbases)
{
/* We might be able to shorten the amount of work we do by
only doing this for vtables that come from virtual bases
that have differing offsets, but don't want to miss any
entries. */
fixup_vtable_deltas (vbases, 1, t);
vbases = TREE_CHAIN (vbases);
}
}
/* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we
......@@ -3736,6 +3719,27 @@ finish_struct_1 (t, warn_anon)
TREE_VALUE (pending_hard_virtuals));
pending_hard_virtuals = TREE_CHAIN (pending_hard_virtuals);
}
if (TYPE_USES_VIRTUAL_BASECLASSES (t))
{
tree vbases;
/* Now fixup any virtual function entries from virtual bases
that have different deltas. This has to come after we do the
pending hard virtuals, as we might have a function that comes
from multiple virtual base instances that is only overridden
by a hard virtual above. */
vbases = CLASSTYPE_VBASECLASSES (t);
while (vbases)
{
/* We might be able to shorten the amount of work we do by
only doing this for vtables that come from virtual bases
that have differing offsets, but don't want to miss any
entries. */
fixup_vtable_deltas (vbases, 1, t);
vbases = TREE_CHAIN (vbases);
}
}
doing_hard_virtuals = 0;
/* Under our model of GC, every C++ class gets its own virtual
......@@ -4045,8 +4049,8 @@ finish_struct (t, list_of_fieldlists, warn_anon)
tree list_of_fieldlists;
int warn_anon;
{
tree fields = NULL_TREE, fn_fields, *tail;
tree *tail_user_methods = &CLASSTYPE_METHODS (t);
tree fields = NULL_TREE;
tree *tail = &TYPE_METHODS (t);
tree name = TYPE_NAME (t);
tree x, last_x = NULL_TREE;
enum access_type access;
......@@ -4071,7 +4075,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
if (IS_SIGNATURE (t))
append_signature_fields (list_of_fieldlists);
tail = &fn_fields;
if (last_x && list_of_fieldlists)
TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists);
......@@ -4130,11 +4133,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
{
if (last_x)
TREE_CHAIN (last_x) = TREE_CHAIN (x);
/* Link x onto end of fn_fields and CLASSTYPE_METHODS. */
/* Link x onto end of TYPE_METHODS. */
*tail = x;
tail = &TREE_CHAIN (x);
*tail_user_methods = x;
tail_user_methods = &DECL_NEXT_METHOD (x);
continue;
}
......@@ -4167,12 +4168,12 @@ finish_struct (t, list_of_fieldlists, warn_anon)
}
*tail = NULL_TREE;
*tail_user_methods = NULL_TREE;
TYPE_FIELDS (t) = fields;
if (0 && processing_template_defn)
{
CLASSTYPE_METHOD_VEC (t) = finish_struct_methods (t, fn_fields, 1);
CLASSTYPE_METHOD_VEC (t)
= finish_struct_methods (t, TYPE_METHODS (t), 1);
return t;
}
else
......@@ -4671,6 +4672,7 @@ instantiate_type (lhstype, rhs, complain)
return error_mark_node;
return build_vfn_ref (&base_ptr, base, DECL_VINDEX (function));
}
mark_used (function);
return function;
}
......@@ -4687,6 +4689,7 @@ instantiate_type (lhstype, rhs, complain)
if (field)
{
TREE_OPERAND (rhs, 1) = field;
mark_used (field);
return rhs;
}
......@@ -4760,7 +4763,10 @@ instantiate_type (lhstype, rhs, complain)
if (! comptypes (lhstype, TREE_TYPE (elem), 1))
elem = DECL_CHAIN (elem);
else
return elem;
{
mark_used (elem);
return elem;
}
/* No exact match found, look for a compatible template. */
{
......@@ -4815,6 +4821,7 @@ instantiate_type (lhstype, rhs, complain)
}
return error_mark_node;
}
mark_used (save_elem);
return save_elem;
}
if (complain)
......@@ -4848,7 +4855,10 @@ instantiate_type (lhstype, rhs, complain)
elem = TREE_VALUE (baselink);
while (elem)
if (comptypes (lhstype, TREE_TYPE (elem), 1))
return elem;
{
mark_used (elem);
return elem;
}
else
elem = DECL_CHAIN (elem);
}
......@@ -4874,6 +4884,7 @@ instantiate_type (lhstype, rhs, complain)
error ("ambiguous overload for overloaded method requested");
return error_mark_node;
}
mark_used (save_elem);
return save_elem;
}
name = DECL_NAME (TREE_VALUE (rhs));
......
......@@ -636,10 +636,6 @@ struct lang_type
/* The is the VAR_DECL that contains NODE's rtti. */
#define CLASSTYPE_RTTI(NODE) (TYPE_LANG_SPECIFIC(NODE)->rtti)
/* List of all explicit methods (chained using DECL_NEXT_METHOD),
in order they were parsed. */
#define CLASSTYPE_METHODS(NODE) (TYPE_LANG_SPECIFIC(NODE)->methods)
/* Nonzero means that this _CLASSTYPE node overloads operator(). */
#define TYPE_OVERLOADS_CALL_EXPR(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_call_overloaded)
......@@ -660,7 +656,7 @@ struct lang_type
#define TYPE_USES_VIRTUAL_BASECLASSES(NODE) (TREE_LANG_FLAG_3(NODE))
/* List of lists of member functions defined in this class. */
#define CLASSTYPE_METHOD_VEC(NODE) TYPE_METHODS(NODE)
#define CLASSTYPE_METHOD_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->methods)
/* The first type conversion operator in the class (the others can be
searched with TREE_CHAIN), or the first non-constructor function if
......@@ -924,7 +920,7 @@ struct lang_type
#define TYPE_RAISES_EXCEPTIONS(NODE) TYPE_NONCOPIED_PARTS (NODE)
/* The binding level associated with the namespace. */
#define NAMESPACE_LEVEL(NODE) ((NODE)->decl.arguments)
#define NAMESPACE_LEVEL(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.level)
struct lang_decl_flags
{
......@@ -960,6 +956,7 @@ struct lang_decl_flags
tree access;
tree context;
tree memfunc_pointer_to;
struct binding_level *level;
};
struct lang_decl
......@@ -969,7 +966,6 @@ struct lang_decl
struct template_info *template_info;
tree main_decl_variant;
struct pending_inline *pending_inline_info;
tree next_method;
tree chain;
};
......@@ -1068,9 +1064,6 @@ struct lang_decl
#define DECL_CHAIN(NODE) (TREE_CHAIN (NODE))
#endif
/* Next method in CLASSTYPE_METHODS list. */
#define DECL_NEXT_METHOD(NODE) (DECL_LANG_SPECIFIC(NODE)->next_method)
/* In a VAR_DECL for a variable declared in a for statement,
this is the shadowed variable. */
#define DECL_SHADOWED_FOR_VAR(NODE) DECL_RESULT(NODE)
......@@ -1401,6 +1394,9 @@ extern int flag_new_for_scope;
#define UPT_TEMPLATE(NODE) TREE_PURPOSE(TYPE_VALUES(NODE))
#define UPT_PARMS(NODE) TREE_VALUE(TYPE_VALUES(NODE))
#define builtin_function(NAME, TYPE, CODE, LIBNAME) \
define_function (NAME, TYPE, CODE, (void (*)())pushdecl, LIBNAME)
/* An enumeration of the kind of tags that C++ accepts. */
enum tag_types { record_type, class_type, union_type, enum_type,
signature_type };
......@@ -1809,6 +1805,12 @@ extern int flag_alt_external_templates;
extern int flag_implicit_templates;
/* Nonzero if we want to emit defined symbols with common-like linkage as
weak symbols where possible, in order to conform to C++ semantics.
Otherwise, emit them as local symbols. */
extern int flag_weak;
/* Current end of entries in the gc obstack for stack pointer variables. */
extern int current_function_obstack_index;
......@@ -1844,6 +1846,9 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
LOOKUP_HAS_IN_CHARGE means that the "in charge" variable is already
in the parameter list.
LOOKUP_ONLYCONVERTING means that non-conversion constructors are not tried.
INDIRECT_BIND means that if a temporary is created, it should be created so
that it lives only as long as WITH_CLEANUP_EXPRs live, else if a temporary
is created then it should live as long as the current variable bindings.
LOOKUP_SPECULATIVELY means return NULL_TREE if we cannot find what we are
after. Note, LOOKUP_COMPLAIN is checked and error messages printed
before LOOKUP_SPECULATIVELY is checked.
......@@ -1860,7 +1865,7 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
#define LOOKUP_HAS_IN_CHARGE (32)
#define LOOKUP_SPECULATIVELY (64)
#define LOOKUP_ONLYCONVERTING (128)
/* 256 is free */
#define INDIRECT_BIND (256)
#define LOOKUP_NO_CONVERSION (512)
#define LOOKUP_DESTRUCTOR (512)
......@@ -2131,6 +2136,8 @@ extern void init_exception_processing PROTO((void));
extern void expand_builtin_throw PROTO((void));
extern void expand_start_eh_spec PROTO((void));
extern void expand_end_eh_spec PROTO((tree));
extern tree build_cleanup PROTO((tree));
extern tree start_anon_func PROTO((void));
/* in expr.c */
/* skip cplus_expand_expr */
......@@ -2395,6 +2402,7 @@ extern tree array_type_nelts_total PROTO((tree));
extern tree array_type_nelts_top PROTO((tree));
extern tree break_out_target_exprs PROTO((tree));
extern tree build_unsave_expr PROTO((tree));
extern tree unsave_expr PROTO((tree));
extern int cp_expand_decl_cleanup PROTO((tree, tree));
/* in typeck.c */
......
......@@ -311,6 +311,7 @@ convert_to_pointer_force (type, expr)
value we have to begin with is in ARG.
FLAGS controls how we manage access checking.
INDIRECT_BIND in FLAGS controls how any temporarys are generated.
CHECKCONST controls if we report error messages on const subversion. */
static tree
build_up_reference (type, arg, flags, checkconst)
......@@ -589,7 +590,15 @@ build_up_reference (type, arg, flags, checkconst)
{
tree temp;
if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
if (flags&INDIRECT_BIND)
{
tree slot = build (VAR_DECL, argtype);
layout_decl (slot, 0);
rval = build (TARGET_EXPR, argtype, slot, arg, 0);
rval = build1 (ADDR_EXPR, type, rval);
goto done;
}
else if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
{
temp = build_cplus_new (argtype, targ, 1);
if (TREE_CODE (temp) == WITH_CLEANUP_EXPR)
......@@ -1634,8 +1643,13 @@ build_expr_type_conversion (desires, expr, complain)
}
if (winner)
return build_type_conversion_1 (TREE_VALUE (winner), basetype, expr,
TREE_PURPOSE (winner), 1);
{
tree type = TREE_VALUE (winner);
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
return build_type_conversion_1 (type, basetype, expr,
TREE_PURPOSE (winner), 1);
}
return NULL_TREE;
}
......
......@@ -36,7 +36,6 @@ Boston, MA 02111-1307, USA. */
#include "decl.h"
#include "lex.h"
#include "output.h"
#include "defaults.h"
extern tree get_file_function_name ();
extern tree cleanups_this_call;
......@@ -369,6 +368,12 @@ int flag_check_new;
int flag_new_for_scope = 1;
/* Nonzero if we want to emit defined symbols with common-like linkage as
weak symbols where possible, in order to conform to C++ semantics.
Otherwise, emit them as local symbols. */
int flag_weak = 1;
/* Table of language-dependent -f options.
STRING is the option name. VARIABLE is the address of the variable.
ON_VALUE is the value to store in VARIABLE
......@@ -416,7 +421,8 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{"operator-names", &flag_operator_names, 1},
{"check-new", &flag_check_new, 1},
{"repo", &flag_use_repository, 1},
{"for-scope", &flag_new_for_scope, 2}
{"for-scope", &flag_new_for_scope, 2},
{"weak", &flag_weak, 1}
};
/* Decode the string P as a language-specific option.
......@@ -906,7 +912,7 @@ grokclassfn (ctype, cname, function, flags, quals)
/* Mark the artificial `__in_chrg' parameter as "artificial". */
SET_DECL_ARTIFICIAL (parm);
DECL_ARG_TYPE (parm) = integer_type_node;
DECL_REGISTER (parm) = 1;
TREE_READONLY (parm) = 1;
TREE_CHAIN (parm) = last_function_parms;
last_function_parms = parm;
}
......@@ -948,18 +954,11 @@ grokclassfn (ctype, cname, function, flags, quals)
buf[len] = '\0';
strcat (buf, dbuf);
DECL_ASSEMBLER_NAME (function) = get_identifier (buf);
parm = build_decl (PARM_DECL, in_charge_identifier, const_integer_type);
parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node);
/* Mark the artificial `__in_chrg' parameter as "artificial". */
SET_DECL_ARTIFICIAL (parm);
TREE_USED (parm) = 1;
#if 0
/* We don't need to mark the __in_chrg parameter itself as `const'
since its type is already `const int'. In fact we MUST NOT mark
it as `const' cuz that will screw up the debug info (causing it
to say that the type of __in_chrg is `const const int'). */
TREE_READONLY (parm) = 1;
#endif
DECL_ARG_TYPE (parm) = const_integer_type;
DECL_ARG_TYPE (parm) = integer_type_node;
/* This is the same chain as DECL_ARGUMENTS (...). */
TREE_CHAIN (last_function_parms) = parm;
......@@ -2030,7 +2029,7 @@ constructor_name_full (thing)
if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))
{
if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing))
thing = DECL_NAME (TREE_VEC_ELT (TYPE_METHODS (thing), 0));
thing = DECL_NAME (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0));
else
thing = TYPE_NAME (thing);
}
......@@ -2479,6 +2478,8 @@ coerce_delete_type (type)
return type;
}
extern tree abort_fndecl;
static void
mark_vtable_entries (decl)
tree decl;
......@@ -2489,16 +2490,12 @@ mark_vtable_entries (decl)
for (; entries; entries = TREE_CHAIN (entries))
{
tree fnaddr = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries));
tree fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries)
: 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;
if (flag_vtable_thunks)
fnaddr = TREE_VALUE (entries);
TREE_OPERAND (fnaddr, 0) = fn = abort_fndecl;
}
if (DECL_LANG_SPECIFIC (fn) && DECL_ABSTRACT_VIRTUAL_P (fn))
TREE_OPERAND (fnaddr, 0) = fn = abort_fndecl;
assemble_external (fn);
}
}
......@@ -2541,8 +2538,8 @@ import_export_vtable (decl, type, final)
if (! found && ! final)
{
tree method;
for (method = CLASSTYPE_METHODS (type); method != NULL_TREE;
method = DECL_NEXT_METHOD (method))
for (method = TYPE_METHODS (type); method != NULL_TREE;
method = TREE_CHAIN (method))
if (DECL_VINDEX (method) != NULL_TREE
&& ! DECL_THIS_INLINE (method)
&& ! DECL_ABSTRACT_VIRTUAL_P (method))
......@@ -2558,7 +2555,7 @@ import_export_vtable (decl, type, final)
if (TREE_PUBLIC (decl))
cp_error ("all virtual functions redeclared inline");
#endif
if (SUPPORTS_WEAK)
if (flag_weak)
DECL_WEAK (decl) = 1;
else
TREE_PUBLIC (decl) = 0;
......@@ -2597,8 +2594,8 @@ finish_prevtable_vardecl (prev, vars)
&& ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
{
tree method;
for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE;
method = DECL_NEXT_METHOD (method))
for (method = TYPE_METHODS (ctype); method != NULL_TREE;
method = TREE_CHAIN (method))
{
if (DECL_VINDEX (method) != NULL_TREE
&& !DECL_THIS_INLINE (method)
......@@ -2782,7 +2779,7 @@ import_export_inline (decl)
{
if (DECL_IMPLICIT_INSTANTIATION (decl) && flag_implicit_templates)
{
if (SUPPORTS_WEAK)
if (flag_weak)
DECL_WEAK (decl) = 1;
else
TREE_PUBLIC (decl) = 0;
......@@ -2799,14 +2796,14 @@ import_export_inline (decl)
= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
|| (DECL_THIS_INLINE (decl) && ! flag_implement_inlines));
}
else if (SUPPORTS_WEAK)
else if (flag_weak)
DECL_WEAK (decl) = 1;
else
TREE_PUBLIC (decl) = 0;
}
else if (DECL_C_STATIC (decl))
TREE_PUBLIC (decl) = 0;
else if (SUPPORTS_WEAK)
else if (flag_weak)
DECL_WEAK (decl) = 1;
else
TREE_PUBLIC (decl) = 0;
......@@ -2814,6 +2811,26 @@ import_export_inline (decl)
DECL_INTERFACE_KNOWN (decl) = 1;
}
tree
build_cleanup (decl)
tree decl;
{
tree temp;
tree type = TREE_TYPE (decl);
if (TREE_CODE (type) == ARRAY_TYPE)
temp = decl;
else
{
mark_addressable (decl);
temp = build1 (ADDR_EXPR, build_pointer_type (type), decl);
}
temp = build_delete (TREE_TYPE (temp), temp,
integer_two_node,
LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
return temp;
}
extern int parse_time, varconst_time;
#define TIMEVAR(VAR, BODY) \
......@@ -2895,14 +2912,12 @@ finish_file ()
{
tree decl = TREE_VALUE (vars);
tree type = TREE_TYPE (decl);
if (TYPE_NEEDS_DESTRUCTOR (type))
if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars))
{
needs_cleaning = 1;
needs_messing_up = 1;
break;
}
else
needs_messing_up |= TYPE_NEEDS_CONSTRUCTING (type);
vars = TREE_CHAIN (vars);
}
......@@ -2930,23 +2945,10 @@ finish_file ()
tree type = TREE_TYPE (decl);
tree temp = TREE_PURPOSE (vars);
if (TYPE_NEEDS_DESTRUCTOR (type))
if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars))
{
if (TREE_STATIC (vars))
expand_start_cond (build_binary_op (NE_EXPR, temp, integer_zero_node, 1), 0);
if (TREE_CODE (type) == ARRAY_TYPE)
temp = decl;
else
{
mark_addressable (decl);
temp = build1 (ADDR_EXPR, build_pointer_type (type), decl);
}
temp = build_delete (TREE_TYPE (temp), temp,
integer_two_node, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
temp = build_cleanup (decl);
expand_expr_stmt (temp);
if (TREE_STATIC (vars))
expand_end_cond ();
}
}
......@@ -2987,9 +2989,15 @@ finish_file ()
while (vars)
{
extern int temp_slot_level;
extern int target_temp_slot_level;
tree decl = TREE_VALUE (vars);
tree init = TREE_PURPOSE (vars);
tree old_cleanups = cleanups_this_call;
int old_temp_level = target_temp_slot_level;
push_temp_slots ();
push_temp_slots ();
target_temp_slot_level = temp_slot_level;
/* If this was a static attribute within some function's scope,
then don't initialize it here. Also, don't bother
......@@ -3024,7 +3032,6 @@ finish_file ()
TREE_VEC_ELT (init, 1),
TREE_VEC_ELT (init, 2), 0),
const0_rtx, VOIDmode, 0);
free_temp_slots ();
}
else
expand_assignment (decl, init, 0, 0);
......@@ -3037,14 +3044,12 @@ finish_file ()
{
/* a `new' expression at top level. */
expand_expr (decl, const0_rtx, VOIDmode, 0);
free_temp_slots ();
if (TREE_CODE (init) == TREE_VEC)
{
expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0),
TREE_VEC_ELT (init, 1),
TREE_VEC_ELT (init, 2), 0),
const0_rtx, VOIDmode, 0);
free_temp_slots ();
}
else
expand_aggr_init (build_indirect_ref (decl, NULL_PTR), init, 0, 0);
......@@ -3053,9 +3058,14 @@ finish_file ()
else if (decl == error_mark_node)
;
else my_friendly_abort (22);
vars = TREE_CHAIN (vars);
/* Cleanup any temporaries needed for the initial value. */
expand_cleanups_to (old_cleanups);
pop_temp_slots ();
pop_temp_slots ();
target_temp_slot_level = old_temp_level;
vars = TREE_CHAIN (vars);
}
for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
......@@ -3509,3 +3519,11 @@ check_default_args (x)
}
}
}
void
mark_used (decl)
tree decl;
{
TREE_USED (decl) = 1;
assemble_external (decl);
}
......@@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "tree.h"
#include <stdio.h>
#include <ctype.h>
/* cp_printer is the type of a function which converts an argument into
......@@ -195,8 +196,7 @@ cp_sprintf (format, arglist)
char *format;
arglist_dcl
{
extern errorfn sprintf;
cp_thing (sprintf, 0, format, arglist);
cp_thing ((errorfn *) sprintf, 0, format, arglist);
}
void
......
......@@ -950,12 +950,12 @@ dump_expr (t, nop)
}
else if (type == boolean_type_node)
{
if (t == boolean_false_node)
if (t == boolean_false_node
|| (TREE_INT_CST_LOW (t) == 0
&& TREE_INT_CST_HIGH (t) == 0))
OB_PUTS ("false");
else if (t == boolean_true_node)
OB_PUTS ("true");
else
my_friendly_abort (366);
}
else if (type == char_type_node)
{
......
......@@ -43,6 +43,8 @@ Boston, MA 02111-1307, USA. */
line. Perhaps this was not intended. */
tree current_base_init_list, current_member_init_list;
extern tree cleanups_this_call;
void emit_base_init ();
void check_base_init ();
static void expand_aggr_vbase_init ();
......@@ -160,6 +162,13 @@ perform_member_init (member, name, init, explicit, protect_list)
{
tree decl;
tree type = TREE_TYPE (member);
extern int temp_slot_level;
extern int target_temp_slot_level;
tree old_cleanups = cleanups_this_call;
int old_temp_level = target_temp_slot_level;
push_temp_slots ();
push_temp_slots ();
target_temp_slot_level = temp_slot_level;
if (TYPE_NEEDS_CONSTRUCTING (type)
|| (init && TYPE_HAS_CONSTRUCTOR (type)))
......@@ -219,7 +228,16 @@ perform_member_init (member, name, init, explicit, protect_list)
expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
}
}
expand_cleanups_to (NULL_TREE);
expand_cleanups_to (old_cleanups);
pop_temp_slots ();
pop_temp_slots ();
target_temp_slot_level = old_temp_level;
/* There might something left from building the trees. */
if (cleanups_this_call)
{
expand_cleanups_to (NULL_TREE);
}
free_temp_slots ();
if (TYPE_NEEDS_DESTRUCTOR (type))
{
......@@ -577,11 +595,28 @@ emit_base_init (t, immediately)
if (init != void_list_node)
{
extern int temp_slot_level;
extern int target_temp_slot_level;
tree old_cleanups = cleanups_this_call;
int old_temp_level = target_temp_slot_level;
push_temp_slots ();
push_temp_slots ();
target_temp_slot_level = temp_slot_level;
member = convert_pointer_to_real (base_binfo, current_class_decl);
expand_aggr_init_1 (base_binfo, 0,
build_indirect_ref (member, NULL_PTR), init,
BINFO_OFFSET_ZEROP (base_binfo), LOOKUP_NORMAL);
expand_cleanups_to (NULL_TREE);
expand_cleanups_to (old_cleanups);
pop_temp_slots ();
pop_temp_slots ();
target_temp_slot_level = old_temp_level;
/* There might something left from building the trees. */
if (cleanups_this_call)
{
expand_cleanups_to (NULL_TREE);
}
free_temp_slots ();
}
if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))
......@@ -749,11 +784,30 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
{
tree init = purpose_member (binfo, init_list);
tree ref = build_indirect_ref (addr, NULL_PTR);
extern int temp_slot_level;
extern int target_temp_slot_level;
tree old_cleanups = cleanups_this_call;
int old_temp_level = target_temp_slot_level;
push_temp_slots ();
push_temp_slots ();
target_temp_slot_level = temp_slot_level;
if (init)
init = TREE_VALUE (init);
/* Call constructors, but don't set up vtables. */
expand_aggr_init_1 (binfo, exp, ref, init, 0, LOOKUP_COMPLAIN);
expand_cleanups_to (NULL_TREE);
expand_cleanups_to (old_cleanups);
pop_temp_slots ();
pop_temp_slots ();
target_temp_slot_level = old_temp_level;
/* There might something left from building the trees. */
if (cleanups_this_call)
{
expand_cleanups_to (NULL_TREE);
}
free_temp_slots ();
}
/* Initialize this object's virtual base class pointers. This must be
......@@ -818,8 +872,7 @@ do_member_init (s_id, name, init)
/* Function to give error message if member initialization specification
is erroneous. FIELD is the member we decided to initialize.
TYPE is the type for which the initialization is being performed.
FIELD must be a member of TYPE, or the base type from which FIELD
comes must not need a constructor.
FIELD must be a member of TYPE.
MEMBER_NAME is the name of the member. */
......@@ -831,23 +884,12 @@ member_init_ok_or_else (field, type, member_name)
{
if (field == error_mark_node)
return 0;
if (field == NULL_TREE)
if (field == NULL_TREE || DECL_CONTEXT (field) != type)
{
cp_error ("class `%T' does not have any field named `%s'", type,
member_name);
return 0;
}
if (DECL_CONTEXT (field) != type
&& TYPE_NEEDS_CONSTRUCTING (DECL_CONTEXT (field)))
{
if (current_function_decl && DECL_CONSTRUCTOR_P (current_function_decl))
cp_error ("initialization of `%D' inside constructor for `%T'",
field, type);
else
cp_error ("member `%D' comes from base class needing constructor",
field);
return 0;
}
if (TREE_STATIC (field))
{
cp_error ("field `%#D' is static; only point of initialization is its declaration",
......@@ -960,6 +1002,12 @@ expand_member_init (exp, name, init)
return;
}
if (warn_reorder && current_member_init_list)
{
warning ("base initializer for `%s'", IDENTIFIER_POINTER (name));
warning (" will be re-ordered to precede member initializations");
}
base_init = build_tree_list (name, init);
TREE_TYPE (base_init) = basetype;
current_base_init_list = chainon (current_base_init_list, base_init);
......@@ -1354,12 +1402,15 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
}
else
{
#if 0
/* This causes testcase return2.C to fail. */
init = TREE_OPERAND (init, 1);
init = build (CALL_EXPR, init_type,
TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), 0);
TREE_SIDE_EFFECTS (init) = 1;
if (init_list)
TREE_VALUE (init_list) = init;
#endif
}
}
......@@ -1508,7 +1559,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
cp_error ("ambiguity between conversion to `%T' and constructor",
type);
else
expand_assignment (exp, rval, 0, 0);
expand_aggr_init_1 (binfo, true_exp, exp, rval, alias_this, flags);
return;
}
}
......@@ -1920,7 +1971,7 @@ build_offset_ref (cname, name)
if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == VAR_DECL
|| TREE_CODE (t) == CONST_DECL)
{
TREE_USED (t) = 1;
mark_used (t);
return t;
}
if (TREE_CODE (t) == FIELD_DECL)
......@@ -2010,7 +2061,7 @@ build_offset_ref (cname, name)
error ("in this context");
return error_mark_node;
}
assemble_external (t);
mark_used (t);
return build (OFFSET_REF, TREE_TYPE (t), decl, t);
}
......@@ -2037,8 +2088,10 @@ build_offset_ref (cname, name)
|| ! allocation_temporary_p ()))
fnfields = copy_list (fnfields);
#if 0
for (t = TREE_VALUE (fnfields); t; t = DECL_CHAIN (t))
assemble_external (t);
#endif
t = build_tree_list (error_mark_node, fnfields);
TREE_TYPE (t) = build_offset_type (type, unknown_type_node);
......@@ -2070,8 +2123,7 @@ build_offset_ref (cname, name)
values can be returned without further ado. */
if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL)
{
assemble_external (t);
TREE_USED (t) = 1;
mark_used (t);
return t;
}
......
......@@ -86,6 +86,8 @@ Boston, MA 02111-1307, USA. */
"-fno-this-is-variable",
"-fvtable-thunks",
"-fno-vtable-thunks",
"-fweak",
"-fno-weak",
"-fxref",
"-fno-xref",
......
......@@ -883,13 +883,16 @@ yyprint (file, yychar, yylval)
static int *reduce_count;
int *token_count;
#if 0
#define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0]))
#define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0]))
#endif
int *
init_parse ()
{
#ifdef GATHER_STATISTICS
#ifdef REDUCE_LENGTH
reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1));
bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1));
reduce_count += 1;
......@@ -897,10 +900,12 @@ init_parse ()
bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1));
token_count += 1;
#endif
#endif
return token_count;
}
#ifdef GATHER_STATISTICS
#ifdef REDUCE_LENGTH
void
yyhook (yyn)
int yyn;
......@@ -922,11 +927,13 @@ token_cmp (p, q)
return token_count[*q] - token_count[*p];
}
#endif
#endif
void
print_parse_statistics ()
{
#ifdef GATHER_STATISTICS
#ifdef REDUCE_LENGTH
#if YYDEBUG != 0
int i;
int maxlen = REDUCE_LENGTH;
......@@ -969,6 +976,7 @@ print_parse_statistics ()
fprintf (stderr, "\n");
#endif
#endif
#endif
}
/* Sets the value of the 'yydebug' variable to VALUE.
......@@ -2590,6 +2598,10 @@ linenum:
p->name = input_filename;
input_file_stack = p;
input_file_stack_tick++;
#ifdef DBX_DEBUGGING_INFO
if (write_symbols == DBX_DEBUG)
dbxout_start_new_source_file (input_filename);
#endif
#ifdef DWARF_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
&& write_symbols == DWARF_DEBUG)
......@@ -2627,6 +2639,10 @@ linenum:
input_file_stack = p->next;
free (p);
input_file_stack_tick++;
#ifdef DBX_DEBUGGING_INFO
if (write_symbols == DBX_DEBUG)
dbxout_resume_previous_source_file ();
#endif
#ifdef DWARF_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
&& write_symbols == DWARF_DEBUG)
......@@ -2872,6 +2888,9 @@ do_identifier (token)
{
register tree id = lastiddecl;
if (IDENTIFIER_OPNAME_P (token))
id = lookup_name (token, 0);
if (yychar == YYEMPTY)
yychar = yylex ();
/* Scope class declarations before global
......@@ -2920,7 +2939,14 @@ do_identifier (token)
if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node)
return id;
}
if (yychar == '(' || yychar == LEFT_RIGHT)
if (IDENTIFIER_OPNAME_P (token))
{
if (token != ansi_opname[ERROR_MARK])
cp_error ("operator %O not defined", token);
id = error_mark_node;
}
else if (yychar == '(' || yychar == LEFT_RIGHT)
{
id = implicitly_declare (token);
}
......@@ -4360,8 +4386,10 @@ real_yylex ()
done:
/* yylloc.last_line = lineno; */
#ifdef GATHER_STATISTICS
#ifdef REDUCE_LENGTH
token_count[value] += 1;
#endif
#endif
return value;
}
......
......@@ -178,8 +178,13 @@ report_type_mismatch (cp, parmtypes, name_kind)
/* Happens when the implicit object parameter is rejected. */
my_friendly_assert (! TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes))),
241);
cp_error ("call to non-const %s `%#D' with const object",
name_kind, cp->function);
if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes))))
&& ! TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (cp->function))))))
cp_error ("call to non-volatile %s `%#D' with volatile object",
name_kind, cp->function);
else
cp_error ("call to non-const %s `%#D' with const object",
name_kind, cp->function);
return;
}
......@@ -1547,6 +1552,7 @@ hack_identifier (value, name, yychar)
if (really_overloaded_fn (value))
{
#if 0
tree t = get_first_fn (value);
for (; t; t = DECL_CHAIN (t))
{
......@@ -1556,22 +1562,20 @@ hack_identifier (value, name, yychar)
assemble_external (t);
TREE_USED (t) = 1;
}
#endif
}
else if (TREE_CODE (value) == TREE_LIST)
{
/* Ambiguous reference to base members, possibly other cases?. */
tree t = value;
while (t && TREE_CODE (t) == TREE_LIST)
{
assemble_external (TREE_VALUE (t));
TREE_USED (t) = 1;
mark_used (TREE_VALUE (t));
t = TREE_CHAIN (t);
}
}
else
{
assemble_external (value);
TREE_USED (value) = 1;
}
mark_used (value);
if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value))
{
......@@ -1800,14 +1804,17 @@ make_thunk (function, delta)
}
if (thunk == NULL_TREE)
{
thunk = build_decl (THUNK_DECL, thunk_id, TREE_TYPE (func_decl));
thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl));
DECL_RESULT (thunk)
= build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (vtable_entry_type)));
TREE_READONLY (thunk) = TYPE_READONLY (TREE_TYPE (vtable_entry_type));
TREE_THIS_VOLATILE (thunk) = TYPE_VOLATILE (TREE_TYPE (vtable_entry_type));
make_function_rtl (thunk);
TREE_SET_CODE (thunk, THUNK_DECL);
DECL_INITIAL (thunk) = function;
THUNK_DELTA (thunk) = delta;
DECL_EXTERNAL (thunk) = 1;
TREE_PUBLIC (thunk) = 1;
/* So that finish_file can write out any thunks that need to be: */
pushdecl_top_level (thunk);
}
......@@ -1845,16 +1852,11 @@ emit_thunk (thunk_fndecl)
TREE_ASM_WRITTEN (thunk_fndecl) = 1;
if (TREE_PUBLIC (function))
{
TREE_PUBLIC (thunk_fndecl) = 1;
if (DECL_EXTERNAL (function))
{
DECL_EXTERNAL (thunk_fndecl) = 1;
assemble_external (thunk_fndecl);
return;
}
}
if (! TREE_PUBLIC (function))
TREE_PUBLIC (thunk_fndecl) = 0;
if (DECL_EXTERNAL (function))
return;
DECL_EXTERNAL (thunk_fndecl) = 0;
decl_printable_name = thunk_printable_name;
if (current_function_decl)
......
......@@ -661,8 +661,9 @@ fn.def1:
reinit_parse_for_function ();
$$ = NULL_TREE; }
| declmods notype_declarator exception_specification_opt
{ tree specs = strip_attrs ($1);
if (! start_function (specs, $2, $3, NULL_TREE, 0))
{ tree specs, attrs;
split_specs_attrs ($1, &specs, &attrs);
if (! start_function (specs, $2, $3, attrs, 0))
YYERROR1;
reinit_parse_for_function ();
$$ = NULL_TREE; }
......@@ -1306,18 +1307,6 @@ primary:
{
if (TREE_CODE ($$) == BIT_NOT_EXPR)
$$ = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ($$, 0));
else if (IDENTIFIER_OPNAME_P ($$))
{
tree op = $$;
$$ = lookup_name (op, 0);
if ($$ == NULL_TREE)
{
if (op != ansi_opname[ERROR_MARK])
error ("operator %s not defined",
operator_name_string (op));
$$ = error_mark_node;
}
}
else
$$ = do_identifier ($$);
}
......@@ -1531,10 +1520,9 @@ primary:
else
{
if (TREE_CODE ($$) == ADDR_EXPR)
assemble_external (TREE_OPERAND ($$, 0));
mark_used (TREE_OPERAND ($$, 0));
else
assemble_external ($$);
TREE_USED ($$) = 1;
mark_used ($$);
}
if (TREE_CODE ($$) == CONST_DECL)
{
......@@ -3545,6 +3533,9 @@ for.init.statement:
{ if ($1) cplus_expand_expr_stmt ($1); }
| decl
| '{' compstmtend
{ if (pedantic)
pedwarn ("ANSI C++ forbids compound statements inside for initializations");
}
;
/* Either a type-qualifier or nothing. First thing in an `asm' statement. */
......
......@@ -2400,7 +2400,7 @@ do_pending_expansions ()
if (i->interface == 1)
/* OK, it was an implicit instantiation. */
{
if (SUPPORTS_WEAK)
if (flag_weak)
DECL_WEAK (t) = 1;
else
TREE_PUBLIC (t) = 0;
......@@ -2533,6 +2533,8 @@ do_function_instantiation (declspecs, declarator, storage)
fn = IDENTIFIER_GLOBAL_VALUE (name),
fn && DECL_TEMPLATE_INSTANTIATION (fn))
result = fn;
else if (fn && DECL_CONTEXT (fn))
;
else if (name = DECL_NAME (decl), fn = IDENTIFIER_GLOBAL_VALUE (name), fn)
{
for (fn = get_first_fn (fn); fn; fn = DECL_CHAIN (fn))
......
......@@ -3507,11 +3507,17 @@ static void
add_conversions (binfo)
tree binfo;
{
tree tmp = CLASSTYPE_FIRST_CONVERSION (BINFO_TYPE (binfo));
for (; tmp && IDENTIFIER_TYPENAME_P (DECL_NAME (tmp));
tmp = TREE_CHAIN (tmp))
conversions = tree_cons (DECL_NAME (tmp), TREE_TYPE (TREE_TYPE (tmp)),
conversions);
int i;
tree vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
for (i = 1; i < TREE_VEC_LENGTH (vec); ++i)
{
tree tmp = TREE_VEC_ELT (vec, i);
if (! IDENTIFIER_TYPENAME_P (DECL_NAME (tmp)))
break;
conversions = tree_cons (DECL_NAME (tmp), TREE_TYPE (TREE_TYPE (tmp)),
conversions);
}
}
tree
......
......@@ -1766,7 +1766,7 @@ build_component_ref (datum, component, basetype_path, protect)
my_friendly_assert (datum != error_mark_node, 310);
fndecl = build_vfn_ref (&addr, datum, DECL_VINDEX (fndecl));
}
assemble_external (fndecl);
mark_used (fndecl);
return fndecl;
}
if (access == access_protected)
......@@ -1781,8 +1781,10 @@ build_component_ref (datum, component, basetype_path, protect)
not matter unless we're actually calling the function. */
tree t;
#if 0
for (t = TREE_VALUE (fndecls); t; t = DECL_CHAIN (t))
assemble_external (t);
#endif
t = build_tree_list (error_mark_node, fndecls);
TREE_TYPE (t) = build_offset_type (basetype,
......@@ -1809,9 +1811,10 @@ build_component_ref (datum, component, basetype_path, protect)
cp_error ("invalid use of type decl `%#D' as expression", field);
return error_mark_node;
}
if (DECL_RTL (field) != 0)
assemble_external (field);
TREE_USED (field) = 1;
else if (DECL_RTL (field) != 0)
mark_used (field);
else
TREE_USED (field) = 1;
return field;
}
}
......@@ -2347,7 +2350,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
/* Save the intermediate result in a SAVE_EXPR so we don't have to
compute each component of the virtual function pointer twice. */
if (/* !building_cleanup && */ TREE_CODE (aref) == INDIRECT_REF)
if (TREE_CODE (aref) == INDIRECT_REF)
TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
delta = build_binary_op (PLUS_EXPR,
......@@ -2400,7 +2403,7 @@ build_function_call_real (function, params, require_complete, flags)
GNU_xref_call (current_function_decl,
IDENTIFIER_POINTER (name ? name
: TYPE_IDENTIFIER (DECL_CLASS_CONTEXT (function))));
assemble_external (function);
mark_used (function);
fndecl = function;
/* Convert anything with function type to a pointer-to-function. */
......@@ -2426,8 +2429,7 @@ build_function_call_real (function, params, require_complete, flags)
if (DECL_INLINE (function))
{
/* Is it a synthesized method that needs to be synthesized? */
if (DECL_ARTIFICIAL (function) && ! flag_no_inline
&& ! DECL_INITIAL (function)
if (DECL_ARTIFICIAL (function) && ! DECL_INITIAL (function)
/* Kludge: don't synthesize for default args. */
&& current_function_decl)
synthesize_method (function);
......@@ -2438,11 +2440,7 @@ build_function_call_real (function, params, require_complete, flags)
function = build1 (ADDR_EXPR, build_pointer_type (fntype), function);
}
else
{
assemble_external (function);
TREE_USED (function) = 1;
function = default_conversion (function);
}
function = default_conversion (function);
}
else
{
......@@ -2718,7 +2716,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
type = integer_type_node;
#endif
parmval = convert_for_initialization (return_loc, type, val, flags,
parmval = convert_for_initialization (return_loc, type, val,
flags|INDIRECT_BIND,
"argument passing", fndecl, i);
#ifdef PROMOTE_PROTOTYPES
if ((TREE_CODE (type) == INTEGER_TYPE
......@@ -3554,6 +3553,17 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
tree primop0 = get_narrower (op0, &unsignedp0);
tree primop1 = get_narrower (op1, &unsignedp1);
/* Check for comparison of different enum types. */
if (flag_int_enum_equivalence == 0
&& TREE_CODE (TREE_TYPE (orig_op0)) == ENUMERAL_TYPE
&& TREE_CODE (TREE_TYPE (orig_op1)) == ENUMERAL_TYPE
&& TYPE_MAIN_VARIANT (TREE_TYPE (orig_op0))
!= TYPE_MAIN_VARIANT (TREE_TYPE (orig_op1)))
{
cp_warning ("comparison between `%#T' and `%#T'",
TREE_TYPE (orig_op0), TREE_TYPE (orig_op1));
}
/* Give warnings for comparisons between signed and unsigned
quantities that may fail. */
/* Do the checking based on the original operand trees, so that
......@@ -4068,7 +4078,7 @@ build_unary_op (code, xarg, noconvert)
case FIX_ROUND_EXPR:
case FIX_CEIL_EXPR:
{
tree incremented, modify, value;
tree incremented, modify, value, compound;
if (! lvalue_p (arg) && pedantic)
pedwarn ("cast to non-reference type used as lvalue");
arg = stabilize_reference (arg);
......@@ -4081,8 +4091,13 @@ build_unary_op (code, xarg, noconvert)
? PLUS_EXPR : MINUS_EXPR),
argtype, value, inc);
TREE_SIDE_EFFECTS (incremented) = 1;
modify = build_modify_expr (arg, NOP_EXPR, incremented);
return build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
compound = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
/* Eliminate warning about unused result of + or -. */
TREE_NO_UNUSED_WARNING (compound) = 1;
return compound;
}
}
......@@ -4549,8 +4564,6 @@ mark_addressable (exp)
TREE_ADDRESSABLE (x) = 1;
TREE_USED (x) = 1;
TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
if (asm_out_file)
assemble_external (x);
return 1;
default:
......@@ -5563,9 +5576,19 @@ tree
expand_target_expr (t)
tree t;
{
extern int temp_slot_level;
extern int target_temp_slot_level;
int old_temp_level = target_temp_slot_level;
tree xval = make_node (RTL_EXPR);
rtx rtxval;
/* Any TARGET_EXPR temps live only as long as the outer temp level.
Since they are preserved in this new inner level, we know they
will make it into the outer level. */
push_temp_slots ();
target_temp_slot_level = temp_slot_level;
do_pending_stack_adjust ();
start_sequence_for_rtl_expr (xval);
emit_note (0, -1);
......@@ -5576,6 +5599,10 @@ expand_target_expr (t)
end_sequence ();
RTL_EXPR_RTL (xval) = rtxval;
TREE_TYPE (xval) = TREE_TYPE (t);
pop_temp_slots ();
target_temp_slot_level = old_temp_level;
return xval;
}
......
......@@ -569,8 +569,6 @@ store_init_value (decl, init)
if (TREE_CODE (init) == CONSTRUCTOR)
{
tree field;
tree funcs;
int func;
/* Check that we're really an aggregate as ARM 8.4.1 defines it. */
if (CLASSTYPE_N_BASECLASSES (type))
......@@ -588,16 +586,11 @@ store_init_value (decl, init)
cp_error_at ("initializer list construction invalid for `%D'", decl);
cp_error_at ("due to non-public access of member `%D'", field);
}
funcs = TYPE_METHODS (type);
if (funcs)
for (func = 0; func < TREE_VEC_LENGTH (funcs); func++)
for (field = TYPE_METHODS (type); field; field = TREE_CHAIN (field))
if (TREE_PRIVATE (field) || TREE_PROTECTED (field))
{
field = TREE_VEC_ELT (funcs, func);
if (field && (TREE_PRIVATE (field) || TREE_PROTECTED (field)))
{
cp_error_at ("initializer list construction invalid for `%D'", decl);
cp_error_at ("due to non-public access of member `%D'", field);
}
cp_error_at ("initializer list construction invalid for `%D'", decl);
cp_error_at ("due to non-public access of member `%D'", field);
}
}
#endif
......@@ -894,10 +887,16 @@ digest_init (type, init, tail)
return process_init_constructor (type, init, (tree *)0);
else if (TYPE_NON_AGGREGATE_CLASS (type))
{
#if 0
/* This isn't true. */
/* This can only be reached when caller is initializing
ARRAY_TYPE. In that case, we don't want to convert
INIT to TYPE. We will let `expand_vec_init' do it. */
return init;
#else
return convert_for_initialization (0, type, init, LOOKUP_NORMAL,
"initialization", NULL_TREE, 0);
#endif
}
else if (tail != 0)
{
......
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