Commit 4ac14744 by Mike Stump

86th Cygnus<->FSF quick merge

From-SVN: r11974
parent 62cb0901
......@@ -3,6 +3,82 @@ Sat May 11 04:33:50 1996 Doug Evans <dje@canuck.cygnus.com>
* decl2.c (finish_vtable_vardecl): Surround DECL_ONE_ONLY with ifdef.
(finish_file): Likewise.
Wed May 15 14:46:14 1996 Mike Stump <mrs@cygnus.com>
* call.c (build_method_call): Allow implicit & on METHOD_TYPEs,
but pedwarn as the code is bogus.
* typeck.c (decay_conversion): Ditto.
(build_function_call_real): Use build_addr_func instead of
default_conversion. Don't allow pointer-to-method functions down
here.
(build_unary_op): Use real pointer-to-member functions instead of
fake ones.
(build_ptrmemfunc): Use build_addr_func instead of build_unary_op.
(convert_for_assignment): Removed some obsolete code.
* decl2.c (reparse_absdcl_as_expr): Pass current_class_ref to
build_x_function_call instead of current_class_ptr. Only call
digest_init once on an initializer, we do this just checking
TREE_TYPE.
(build_expr_from_tree): Pass current_class_ref to
build_x_function_call instead of current_class_ptr.
* init.c (build_member_call): Ditto.
* pase.y: Ditto.
* error.c (dump_expr): Handle OFFSET_REFs better.
* pt.c (unify): Handle pointer-to-member functions better.
* decl.c (finish_function): Clear out current_class_ref just like
we do for current_class_ptr.
* typeck.c (get_delta_difference): Handle virtual bases better.
Tue May 14 16:37:37 1996 Jason Merrill <jason@yorick.cygnus.com>
* sig.c (build_signature_table_constructor): Use the delta for
the original basetype for this virtual function with thunks.
(build_signature_method_call): We still need to adjust 'this'
with thunks.
Tue May 14 16:27:25 1996 Mike Stump <mrs@cygnus.com>
* call.c (build_addr_func): New routine. Used to get the `real'
address of a function or a method. Needed to avoid getting a
pointer-to-member function.
(build_call): New routine to build CALL_EXPRs.
(build_method_call): Use it.
* cvt.c (convert_to_aggr): Ditto.
* typeck.c (build_function_call_real): Ditto.
* sig.c (build_signature_table_constructor): Use build_addr_func.
* cp-tree.h (build_call, build_addr_func): Declare them.
Tue May 14 12:47:47 1996 Mike Stump <mrs@cygnus.com>
* cp-tree.h (LOOKUP_AGGR): Remove, unused.
* parse.y: Remove uses of LOOKUP_AGGR.
Tue May 14 12:07:51 1996 Mike Stump <mrs@cygnus.com>
* *.[chy]: Rename current_class_decl to current_class_ptr, and
C_C_D to current_class_ref.
Mon May 13 16:55:23 1996 Jason Merrill <jason@yorick.cygnus.com>
* call.c (convert_harshness): Tighten up pointer conversions.
Sat May 11 04:33:50 1996 Doug Evans <dje@canuck.cygnus.com>
* decl2.c (finish_vtable_vardecl): Surround DECL_ONE_ONLY with ifdef.
(finish_file): Likewise.
Fri May 10 11:09:57 1996 Jason Merrill <jason@yorick.cygnus.com>
* cvt.c (convert_fn_ptr): We don't use thunks for pmfs.
* method.c (emit_thunk): Set flag_omit_frame_pointer in default
code.
Thu May 9 18:18:30 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl2.c: Turn on thunks by default where supported.
Tue May 7 20:39:57 1996 Mike Stump <mrs@cygnus.com>
* cp-tree.h (build_overload_call_maybe): Removed.
......
......@@ -506,12 +506,6 @@ convert_harshness (type, parmtype, parm)
if (TREE_CODE (ttl) != VOID_TYPE
&& (TREE_CODE (ttr) != VOID_TYPE || !parm || !integer_zerop (parm)))
{
if (TREE_UNSIGNED (ttl) != TREE_UNSIGNED (ttr))
{
ttl = unsigned_type (ttl);
ttr = unsigned_type (ttr);
penalty = 10;
}
if (comp_target_types (type, parmtype, 1) <= 0)
return EVIL_RETURN (h);
}
......@@ -526,22 +520,18 @@ convert_harshness (type, parmtype, parm)
return EVIL_RETURN (h);
#endif
if (penalty == 10 || ttr == ttl)
if (ttr == ttl)
{
tree tmp1 = TREE_TYPE (type), tmp2 = TREE_TYPE (parmtype);
/* If one was unsigned but the other wasn't, then we need to
do a standard conversion from T to unsigned T. */
if (penalty == 10)
h.code = PROMO_CODE; /* was STD_CODE */
else
h.code = 0;
h.code = 0;
/* Note conversion from `T*' to `const T*',
or `T*' to `volatile T*'. */
if (ttl == ttr
&& ((TYPE_READONLY (tmp1) != TREE_READONLY (tmp2))
|| (TYPE_VOLATILE (tmp1) != TYPE_VOLATILE (tmp2))))
if ((TYPE_READONLY (tmp1) < TREE_READONLY (tmp2))
|| (TYPE_VOLATILE (tmp1) < TYPE_VOLATILE (tmp2)))
h.code = EVIL_CODE;
else if ((TYPE_READONLY (tmp1) != TREE_READONLY (tmp2))
|| (TYPE_VOLATILE (tmp1) != TYPE_VOLATILE (tmp2)))
h.code |= QUAL_CODE;
h.distance = 0;
......@@ -580,8 +570,11 @@ convert_harshness (type, parmtype, parm)
if (ttl != ttr)
{
tree tmp1 = TREE_TYPE (type), tmp2 = TREE_TYPE (parmtype);
if ((TYPE_READONLY (tmp1) != TREE_READONLY (tmp2))
|| (TYPE_VOLATILE (tmp1) != TYPE_VOLATILE (tmp2)))
if ((TYPE_READONLY (tmp1) < TREE_READONLY (tmp2))
|| (TYPE_VOLATILE (tmp1) < TYPE_VOLATILE (tmp2)))
h.code = EVIL_CODE;
else if ((TYPE_READONLY (tmp1) > TREE_READONLY (tmp2))
|| (TYPE_VOLATILE (tmp1) > TYPE_VOLATILE (tmp2)))
h.code |= QUAL_CODE;
}
return h;
......@@ -1192,7 +1185,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
{
tree field, instance;
if (instance_ptr == current_class_decl)
if (instance_ptr == current_class_ptr)
{
/* Check to see if we really have a reference to an instance variable
with `operator()()' overloaded. */
......@@ -1208,7 +1201,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
{
/* If it's a field, try overloading operator (),
or calling if the field is a pointer-to-function. */
instance = build_component_ref_1 (C_C_D, field, 0);
instance = build_component_ref_1 (current_class_ref, field, 0);
if (instance == error_mark_node)
return error_mark_node;
......@@ -1221,7 +1214,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE)
return build_function_call (instance, parms);
else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == METHOD_TYPE)
return build_function_call (instance, tree_cons (NULL_TREE, current_class_decl, parms));
return build_function_call (instance, tree_cons (NULL_TREE, current_class_ptr, parms));
}
}
return NULL_TREE;
......@@ -1527,6 +1520,71 @@ print_n_candidates (candidates, n)
cp_error_at (" %D", candidates[i].function);
}
/* We want the address of a function or method. We avoid creating a
pointer-to-member function. */
tree
build_addr_func (function)
tree function;
{
tree type = TREE_TYPE (function);
/* We have to do these by hand to avoid real pointer to member
functions. */
if (TREE_CODE (type) == METHOD_TYPE)
{
tree addr;
type = build_pointer_type (type);
if (mark_addressable (function) == 0)
return error_mark_node;
addr = build1 (ADDR_EXPR, type, function);
/* Address of a static or external variable or function counts
as a constant */
if (staticp (function))
TREE_CONSTANT (addr) = 1;
function = addr;
}
else
function = default_conversion (function);
return function;
}
/* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or
POINTER_TYPE to those. Note, pointer to member function types
(TYPE_PTRMEMFUNC_P) must be handled by our callers. */
tree
build_call (function, result_type, parms)
tree function, result_type, parms;
{
int is_constructor = 0;
function = build_addr_func (function);
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
{
sorry ("unable to call pointer to member function here");
return error_mark_node;
}
if (TREE_CODE (function) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (TREE_OPERAND (function, 0)))
is_constructor = 1;
function = build_nt (CALL_EXPR, function, parms, NULL_TREE);
TREE_HAS_CONSTRUCTOR (function) = is_constructor;
TREE_TYPE (function) = result_type;
TREE_SIDE_EFFECTS (function) = 1;
return function;
}
/* Build something of the form ptr->method (args)
or object.method (args). This can also build
calls to constructors, and find friends.
......@@ -1739,11 +1797,11 @@ build_method_call (instance, name, parms, basetype_path, flags)
return error_mark_node;
}
}
else if (instance == C_C_D || instance == current_class_decl)
else if (instance == current_class_ref || instance == current_class_ptr)
{
/* When doing initialization, we side-effect the TREE_TYPE of
C_C_D, hence we cannot set up BASETYPE from CURRENT_CLASS_TYPE. */
basetype = TREE_TYPE (C_C_D);
current_class_ref, hence we cannot set up BASETYPE from CURRENT_CLASS_TYPE. */
basetype = TREE_TYPE (current_class_ref);
/* Anything manifestly `this' in constructors and destructors
has a known type, so virtual function tables are not needed. */
......@@ -1765,8 +1823,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
else
{
instance = C_C_D;
instance_ptr = current_class_decl;
instance = current_class_ref;
instance_ptr = current_class_ptr;
basetype_path = TYPE_BINFO (current_class_type);
}
result = build_field_call (basetype_path, instance_ptr, name, parms);
......@@ -1940,9 +1998,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
TREE_VALUE (parm) = resolve_offset_ref (TREE_VALUE (parm));
t = TREE_TYPE (TREE_VALUE (parm));
}
if (TREE_CODE (TREE_VALUE (parm)) == OFFSET_REF
&& TREE_CODE (t) == METHOD_TYPE)
if (TREE_CODE (t) == METHOD_TYPE)
{
cp_pedwarn ("assuming & on `%E'", TREE_VALUE (parm));
TREE_VALUE (parm) = build_unary_op (ADDR_EXPR, TREE_VALUE (parm), 0);
}
#if 0
......@@ -2365,7 +2423,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
type (if it exists) is a pointer to. */
if (DECL_ABSTRACT_VIRTUAL_P (function)
&& instance == C_C_D
&& instance == current_class_ref
&& DECL_CONSTRUCTOR_P (current_function_decl)
&& ! (flags & LOOKUP_NONVIRTUAL)
&& value_member (function, get_abstract_virtuals (basetype)))
......@@ -2422,7 +2480,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
{
/* Let's be nasty to the user now, and give reasonable
error messages. */
instance_ptr = current_class_decl;
instance_ptr = current_class_ptr;
if (instance_ptr)
{
if (basetype != current_class_type)
......@@ -2540,21 +2598,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
GNU_xref_call (current_function_decl,
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function)));
{
int is_constructor
= TREE_CODE (function) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (function);
function = default_conversion (function);
result = build_nt (CALL_EXPR, function, parms, NULL_TREE);
TREE_TYPE (result) = value_type;
TREE_SIDE_EFFECTS (result) = 1;
TREE_HAS_CONSTRUCTOR (result) = is_constructor;
result = convert_from_reference (result);
return result;
}
result = build_call (function, value_type, parms);
result = convert_from_reference (result);
return result;
}
/* Similar to `build_method_call', but for overloaded non-member functions.
......
......@@ -72,7 +72,9 @@ struct class_level
int unused;
};
tree current_class_decl, C_C_D; /* PARM_DECL: the class instance variable */
/* The currect_class_ptr is the pointer to the current class.
current_class_ref is the actual current class. */
tree current_class_ptr, current_class_ref;
/* The following two can be derived from the previous one */
tree current_class_name; /* IDENTIFIER_NODE: name of current class */
......@@ -434,7 +436,7 @@ build_vtbl_ref (instance, idx)
if (TREE_CODE (basetype) == REFERENCE_TYPE)
basetype = TREE_TYPE (basetype);
if (instance == C_C_D)
if (instance == current_class_ref)
vtbl = build_indirect_ref (build_vfield_ref (instance, basetype),
NULL_PTR);
else
......@@ -4494,7 +4496,7 @@ resolves_to_fixed_type_p (instance, nonnull)
}
else if (nonnull)
{
if (instance == current_class_decl
if (instance == current_class_ptr
&& flag_this_is_variable <= 0)
{
/* Some people still use `this = 0' inside destructors. */
......@@ -4941,12 +4943,6 @@ instantiate_type (lhstype, rhs, complain)
tree elem, baselink, name;
int globals = overloaded_globals_p (rhs);
#if 0 /* obsolete */
/* If there's only one function we know about, return that. */
if (globals > 0 && TREE_CHAIN (rhs) == NULL_TREE)
return TREE_VALUE (rhs);
#endif
/* First look for an exact match. Search either overloaded
functions or member functions. May have to undo what
`default_conversion' might do to lhstype. */
......
......@@ -1002,7 +1002,7 @@ struct lang_decl
/* Nonzero for FUNCTION_DECL means that this constructor is known to
not make any assignment to `this', and therefore can be trusted
to return it unchanged. Otherwise, we must re-assign `current_class_decl'
to return it unchanged. Otherwise, we must re-assign `current_class_ptr'
after performing base initializations. */
#define DECL_PRESERVES_THIS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.preserves_first_arg)
......@@ -1551,7 +1551,8 @@ extern tree current_lang_name, lang_name_cplusplus, lang_name_c;
of CURRENT_FUNCTION_DECL due to overloading */
extern tree original_function_name;
extern tree current_class_name, current_class_type, current_class_decl, C_C_D;
extern tree current_class_name, current_class_type;
extern tree current_class_ptr, current_class_ref;
/* in init.c */
extern tree global_base_init_list;
......@@ -1820,8 +1821,6 @@ extern int at_eof;
enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
extern tree current_class_decl, C_C_D; /* PARM_DECL: the class instance variable */
/* The following two can be derived from the previous one */
extern tree current_class_name; /* IDENTIFIER_NODE: name of current class */
extern tree current_class_type; /* _TYPE: the type of the current class */
......@@ -1838,7 +1837,6 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
LOOKUP_COMPLAIN mean complain if no suitable member function
matching the arguments is found.
LOOKUP_NORMAL is just a combination of these two.
LOOKUP_AGGR requires the instance to be of aggregate type.
LOOKUP_NONVIRTUAL means make a direct call to the member function found
LOOKUP_GLOBAL means search through the space of overloaded functions,
as well as the space of member functions.
......@@ -1858,7 +1856,7 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
#define LOOKUP_PROTECT (1)
#define LOOKUP_COMPLAIN (2)
#define LOOKUP_NORMAL (3)
#define LOOKUP_AGGR (4)
/* #define LOOKUP_UNUSED (4) */
#define LOOKUP_NONVIRTUAL (8)
#define LOOKUP_GLOBAL (16)
#define LOOKUP_HAS_IN_CHARGE (32)
......@@ -1941,6 +1939,8 @@ extern int get_arglist_len_in_bytes PROTO((tree));
extern tree build_vfield_ref PROTO((tree, tree));
extern tree find_scoped_type PROTO((tree, tree, tree));
extern tree resolve_scope_to_name PROTO((tree, tree));
extern tree build_call PROTO((tree, tree, tree));
extern tree build_addr_func PROTO((tree));
extern tree build_scoped_method_call PROTO((tree, tree, tree, tree));
extern tree build_method_call PROTO((tree, tree, tree, tree, int));
extern tree build_overload_call_real PROTO((tree, tree, int, struct candidate *, int));
......
......@@ -82,6 +82,7 @@ static tree
convert_fn_ptr (type, expr)
tree type, expr;
{
#if 0 /* We don't use thunks for pmfs. */
if (flag_vtable_thunks)
{
tree intype = TREE_TYPE (expr);
......@@ -104,6 +105,7 @@ convert_fn_ptr (type, expr)
return build1 (NOP_EXPR, type, build_thunk (BINFO_OFFSET (binfo), expr));
}
else
#endif
return build_ptrmemfunc (type, expr, 1);
}
......@@ -477,7 +479,7 @@ build_up_reference (type, arg, flags, checkconst)
case PARM_DECL:
#if 0
if (targ == current_class_decl)
if (targ == current_class_ptr)
{
error ("address of `this' not available");
/* #if 0 */
......@@ -1056,14 +1058,11 @@ convert_to_aggr (type, expr, msgp, protect)
return NULL_TREE;
fntype = TREE_TYPE (function);
function = default_conversion (function);
result = build_nt (CALL_EXPR, function,
convert_arguments (NULL_TREE, TYPE_ARG_TYPES (fntype),
parmlist, NULL_TREE, LOOKUP_NORMAL),
NULL_TREE);
TREE_TYPE (result) = TREE_TYPE (fntype);
TREE_SIDE_EFFECTS (result) = 1;
parmlist = convert_arguments (NULL_TREE, TYPE_ARG_TYPES (fntype),
parmlist, NULL_TREE, LOOKUP_NORMAL);
result = build_call (function, TREE_TYPE (fntype), parmlist);
return result;
}
......@@ -1809,3 +1808,166 @@ type_promotes_to (type)
return cp_build_type_variant (type, constp, volatilep);
}
#if 0
/* Work in progress. Ask jason before removing. */
int
null_ptr_cst (t)
tree t;
{
return (INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t));
}
tree
standard_conversion (to, from, expr)
tree to, from, expr;
{
enum tree_code fcode = TREE_CODE (from);
enum tree_code tcode = TREE_CODE (to);
tree conv;
if (from == to)
return from;
conv = from;
if (fcode == FUNCTION_TYPE)
{
from = build_pointer_type (from);
fcode = TREE_CODE (from);
conv = build1 (LVALUE_CONV, from, conv);
}
else if (fcode == ARRAY_TYPE)
{
from = build_pointer_type (TREE_TYPE (from));
fcode = TREE_CODE (from);
conv = build1 (LVALUE_CONV, from, conv);
}
if ((tcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (to))
&& expr && null_ptr_cst (expr))
{
conv = build1 (CONV_CONV, to, conv);
}
else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE)
{
enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));
enum tree_code utcode = TREE_CODE (TREE_TYPE (to));
if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))),
TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to))), 1))
/* OK for now */;
else if (utcode == VOID_TYPE && ufcode != OFFSET_TYPE
&& ufcode != FUNCTION_TYPE)
{
from = cp_build_type_variant (void_type_node,
TYPE_READONLY (TREE_TYPE (from)),
TYPE_VOLATILE (TREE_TYPE (from)));
conv = build1 (CONV_CONV, from, conv);
}
else if (ufcode == OFFSET_TYPE && utcode == OFFSET_TYPE)
{
tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from));
tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to));
if (DERIVED_FROM_P (tbase, fbase)
&& (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))),
TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to))),
1)))
{
from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from)));
conv = build1 (CONV_CONV, from, conv);
}
else
return 0;
}
else if (IS_AGGR_TYPE (TREE_TYPE (from))
&& IS_AGGR_TYPE (TREE_TYPE (to)))
{
if (DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
{
from = cp_build_type_variant (TREE_TYPE (to),
TYPE_READONLY (TREE_TYPE (from)),
TYPE_VOLATILE (TREE_TYPE (from)));
conv = build1 (CONV_CONV, from, conv);
}
else
return 0;
}
else
return 0;
if (! comptypes (from, to, 1) && comp_ptr_ttypes (to, from))
{
from = to;
conv = build1 (QUAL_CONV, from, conv);
}
}
else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from))
{
tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from));
tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn)));
tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn)));
if (! DERIVED_FROM_P (tbase, fbase)
|| ! comptypes (TREE_TYPE (fromfn), TREE_TYPE (tofn), 1)
|| ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),
TREE_CHAIN (TYPE_ARG_TYPES (tofn)), 1)
|| TYPE_READONLY (fbase) != TYPE_READONLY (tbase)
|| TYPE_VOLATILE (fbase) != TYPE_VOLATILE (tbase))
return 0;
from = cp_build_type_variant (tbase, TYPE_READONLY (fbase),
TYPE_VOLATILE (fbase));
from = build_cplus_method_type (from, TREE_TYPE (fromfn),
TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
conv = build1 (CONV_CONV, from, conv);
}
else if (tcode == BOOLEAN_TYPE)
{
if (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE
|| fcode == POINTER_TYPE)
return build1 (CONV_CONV, to, conv);
else
return 0;
}
else if (INTEGRAL_CODE_P (tcode) || tcode == REAL_TYPE)
{
if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE))
return 0;
else if (to == type_promotes_to (from))
conv = build1 (PROMO_CONV, to, conv);
else
conv = build1 (CONV_CONV, to, conv);
}
else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
&& DERIVED_FROM_P (to, from))
{
conv = build1 (CONV_CONV, to, conv);
}
else
return 0;
return conv;
}
tree
implicit_conversion (to, from, expr, flags)
tree to, from, expr;
int flags;
{
tree conv = standard_conversion (to, from, expr);
if (conv || (flags & LOOKUP_NO_CONVERSION))
return conv;
flags |= LOOKUP_NO_CONVERSION;
/* try constructors */;
/* try conversion ops */;
return conv;
}
#endif
......@@ -3275,7 +3275,7 @@ pushdecl (x)
if (oldlocal != NULL_TREE && TREE_CODE (oldlocal) == PARM_DECL)
warnstring = "declaration of `%s' shadows a parameter";
else if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE
&& current_class_decl
&& current_class_ptr
&& !TREE_STATIC (name))
warnstring = "declaration of `%s' shadows a member of `this'";
else if (oldlocal != NULL_TREE)
......@@ -11075,14 +11075,14 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
push_nested_class (ctype, 1);
/* If we're compiling a friend function, neither of the variables
current_class_decl nor current_class_type will have values. */
current_class_ptr nor current_class_type will have values. */
if (! doing_friend)
{
/* We know that this was set up by `grokclassfn'.
We do not wait until `store_parm_decls', since evil
parse errors may never get us to that point. Here
we keep the consistency between `current_class_type'
and `current_class_decl'. */
and `current_class_ptr'. */
tree t = current_function_parms;
my_friendly_assert (t != NULL_TREE
......@@ -11093,14 +11093,14 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
int i = suspend_momentary ();
/* Fool build_indirect_ref. */
current_class_decl = NULL_TREE;
C_C_D = build_indirect_ref (t, NULL_PTR);
current_class_decl = t;
current_class_ptr = NULL_TREE;
current_class_ref = build_indirect_ref (t, NULL_PTR);
current_class_ptr = t;
resume_momentary (i);
}
else
/* We're having a signature pointer here. */
C_C_D = current_class_decl = t;
current_class_ref = current_class_ptr = t;
}
}
......@@ -11110,7 +11110,7 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
push_nested_class (DECL_CONTEXT (decl1), 2);
else
push_memoized_context (0, 1);
current_class_decl = C_C_D = NULL_TREE;
current_class_ptr = current_class_ref = NULL_TREE;
}
pushlevel (0);
......@@ -11502,7 +11502,7 @@ finish_function (lineno, call_poplevel, nested)
if (current_function_assigns_this)
cond = build (NE_EXPR, boolean_type_node,
current_class_decl, integer_zero_node);
current_class_ptr, integer_zero_node);
else
{
int n_baseclasses = CLASSTYPE_N_BASECLASSES (current_class_type);
......@@ -11541,10 +11541,10 @@ finish_function (lineno, call_poplevel, nested)
/* These are two cases where we cannot delegate deletion. */
if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)
|| TYPE_GETS_REG_DELETE (current_class_type))
exprstmt = build_delete (current_class_type, C_C_D, integer_zero_node,
exprstmt = build_delete (current_class_type, current_class_ref, integer_zero_node,
LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
else
exprstmt = build_delete (current_class_type, C_C_D, in_charge_node,
exprstmt = build_delete (current_class_type, current_class_ref, in_charge_node,
LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
/* If we did not assign to this, then `this' is non-zero at
......@@ -11576,7 +11576,7 @@ finish_function (lineno, call_poplevel, nested)
{
if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (vbases)))
{
tree ptr = convert_pointer_to_vbase (BINFO_TYPE (vbases), current_class_decl);
tree ptr = convert_pointer_to_vbase (BINFO_TYPE (vbases), current_class_ptr);
expand_expr_stmt (build_delete (build_pointer_type (BINFO_TYPE (vbases)),
ptr, integer_zero_node,
LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_HAS_IN_CHARGE, 0));
......@@ -11605,11 +11605,11 @@ finish_function (lineno, call_poplevel, nested)
error_mark_node),
NULL_PTR),
ansi_opname[(int) DELETE_EXPR],
tree_cons (NULL_TREE, current_class_decl,
tree_cons (NULL_TREE, current_class_ptr,
build_tree_list (NULL_TREE, virtual_size)),
NULL_TREE, LOOKUP_NORMAL);
else if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
exprstmt = build_x_delete (ptr_type_node, current_class_decl, 0,
exprstmt = build_x_delete (ptr_type_node, current_class_ptr, 0,
virtual_size);
else
exprstmt = NULL_TREE;
......@@ -11646,16 +11646,16 @@ finish_function (lineno, call_poplevel, nested)
/* Make all virtual function table pointers in non-virtual base
classes point to CURRENT_CLASS_TYPE's virtual function
tables. */
expand_direct_vtbls_init (binfo, binfo, 1, 0, current_class_decl);
expand_direct_vtbls_init (binfo, binfo, 1, 0, current_class_ptr);
if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
expand_indirect_vtbls_init (binfo, C_C_D, current_class_decl);
expand_indirect_vtbls_init (binfo, current_class_ref, current_class_ptr);
}
if (! ok_to_optimize_dtor)
{
cond = build_binary_op (NE_EXPR,
current_class_decl, integer_zero_node, 1);
current_class_ptr, integer_zero_node, 1);
expand_start_cond (cond, 0);
}
......@@ -11691,7 +11691,7 @@ finish_function (lineno, call_poplevel, nested)
expand_end_bindings (decls, decls != NULL_TREE, 0);
poplevel (decls != NULL_TREE, 0, 0);
}
c_expand_return (current_class_decl);
c_expand_return (current_class_ptr);
}
else if (TYPE_MAIN_VARIANT (TREE_TYPE (
DECL_RESULT (current_function_decl))) != void_type_node
......@@ -11715,8 +11715,8 @@ finish_function (lineno, call_poplevel, nested)
if (flag_this_is_variable > 0)
{
cond = build_binary_op (EQ_EXPR,
current_class_decl, integer_zero_node, 1);
thenclause = build_modify_expr (current_class_decl, NOP_EXPR,
current_class_ptr, integer_zero_node, 1);
thenclause = build_modify_expr (current_class_ptr, NOP_EXPR,
build_new (NULL_TREE, current_class_type, void_type_node, 0));
}
......@@ -11769,7 +11769,7 @@ finish_function (lineno, call_poplevel, nested)
poplevel (decls != NULL_TREE, 1, 0);
}
c_expand_return (current_class_decl);
c_expand_return (current_class_ptr);
current_function_assigns_this = 0;
current_function_just_assigned_this = 0;
......@@ -11974,7 +11974,8 @@ finish_function (lineno, call_poplevel, nested)
}
named_label_uses = NULL_TREE;
current_class_decl = NULL_TREE;
current_class_ptr = NULL_TREE;
current_class_ref = NULL_TREE;
}
/* Create the FUNCTION_DECL for a function definition.
......@@ -12412,8 +12413,8 @@ struct cp_function
tree base_init_list;
tree member_init_list;
tree base_init_expr;
tree class_decl;
tree C_C_D;
tree current_class_ptr;
tree current_class_ref;
rtx result_rtx;
struct cp_function *next;
struct binding_level *binding_level;
......@@ -12459,8 +12460,8 @@ push_cp_function_context (context)
p->temp_name_counter = temp_name_counter;
p->base_init_list = current_base_init_list;
p->member_init_list = current_member_init_list;
p->class_decl = current_class_decl;
p->C_C_D = C_C_D;
p->current_class_ptr = current_class_ptr;
p->current_class_ref = current_class_ref;
p->eh_context = push_eh_context ();
}
......@@ -12502,8 +12503,8 @@ pop_cp_function_context (context)
temp_name_counter = p->temp_name_counter;
current_base_init_list = p->base_init_list;
current_member_init_list = p->member_init_list;
current_class_decl = p->class_decl;
C_C_D = p->C_C_D;
current_class_ptr = p->current_class_ptr;
current_class_ref = p->current_class_ref;
pop_eh_context (p->eh_context);
......
......@@ -155,9 +155,13 @@ int warn_implicit = 1;
int warn_ctor_dtor_privacy = 1;
/* True if we want to implement vtables using "thunks".
The default is off now, but will be on later. */
The default is off by default, on if explicitly supported. */
#ifdef ASM_OUTPUT_MI_THUNK
int flag_vtable_thunks = 1;
#else
int flag_vtable_thunks;
#endif
/* True if we want to deal with repository information. */
......@@ -3336,7 +3340,7 @@ reparse_absdcl_as_expr (type, decl)
/* recurse */
decl = reparse_decl_as_expr (type, TREE_OPERAND (decl, 0));
decl = build_x_function_call (decl, NULL_TREE, current_class_decl);
decl = build_x_function_call (decl, NULL_TREE, current_class_ref);
if (TREE_CODE (decl) == CALL_EXPR && TREE_TYPE (decl) != void_type_node)
decl = require_complete_type (decl);
......@@ -3357,7 +3361,8 @@ reparse_absdcl_as_casts (decl, expr)
{
tree type;
if (TREE_CODE (expr) == CONSTRUCTOR)
if (TREE_CODE (expr) == CONSTRUCTOR
&& TREE_TYPE (expr) == 0)
{
type = groktypename (TREE_VALUE (TREE_OPERAND (decl, 1)));
decl = TREE_OPERAND (decl, 0);
......@@ -3556,7 +3561,7 @@ build_expr_from_tree (t)
name = build_expr_from_tree (name);
return build_x_function_call
(name, build_expr_from_tree (TREE_OPERAND (t, 1)),
current_class_decl);
current_class_ref);
}
case COND_EXPR:
......
......@@ -1259,8 +1259,9 @@ dump_expr (t, nop)
dump_expr (TREE_OPERAND (t, 1), 0);
else
{
sorry ("operand of OFFSET_REF not understood");
goto error;
dump_expr (TREE_OPERAND (t, 0), 0);
OB_PUTS (" .* ");
dump_expr (TREE_OPERAND (t, 1), 0);
}
break;
}
......
......@@ -174,7 +174,7 @@ perform_member_init (member, name, init, explicit, protect_list)
if (init != NULL_TREE && TREE_CODE (init) != TREE_LIST)
init = build_tree_list (NULL_TREE, init);
decl = build_component_ref (C_C_D, name, NULL_TREE, explicit);
decl = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
if (explicit
&& TREE_CODE (type) == ARRAY_TYPE
......@@ -220,7 +220,7 @@ perform_member_init (member, name, init, explicit, protect_list)
current_member_init_list. */
if (init || explicit)
{
decl = build_component_ref (C_C_D, name, NULL_TREE, explicit);
decl = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
}
}
......@@ -237,7 +237,7 @@ perform_member_init (member, name, init, explicit, protect_list)
if (TYPE_NEEDS_DESTRUCTOR (type))
{
tree expr = build_component_ref (C_C_D, name, NULL_TREE, explicit);
tree expr = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
expr = build_delete (type, expr, integer_zero_node,
LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
......@@ -487,7 +487,7 @@ build_partial_cleanup_for (binfo)
tree binfo;
{
tree expr = convert_pointer_to_real (binfo,
build_unary_op (ADDR_EXPR, C_C_D, 0));
build_unary_op (ADDR_EXPR, current_class_ref, 0));
return build_delete (TREE_TYPE (expr),
expr,
......@@ -561,7 +561,7 @@ emit_base_init (t, immediately)
tree first_arg = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
expand_start_cond (first_arg, 0);
expand_aggr_vbase_init (t_binfo, C_C_D, current_class_decl,
expand_aggr_vbase_init (t_binfo, current_class_ref, current_class_ptr,
vbase_init_list);
expand_end_cond ();
}
......@@ -596,7 +596,7 @@ emit_base_init (t, immediately)
push_temp_slots ();
target_temp_slot_level = temp_slot_level;
member = convert_pointer_to_real (base_binfo, current_class_decl);
member = convert_pointer_to_real (base_binfo, current_class_ptr);
expand_aggr_init_1 (base_binfo, NULL_TREE,
build_indirect_ref (member, NULL_PTR), init,
BINFO_OFFSET_ZEROP (base_binfo), LOOKUP_NORMAL);
......@@ -626,11 +626,11 @@ emit_base_init (t, immediately)
/* Initialize all the virtual function table fields that
do come from virtual base classes. */
if (TYPE_USES_VIRTUAL_BASECLASSES (t))
expand_indirect_vtbls_init (t_binfo, C_C_D, current_class_decl);
expand_indirect_vtbls_init (t_binfo, current_class_ref, current_class_ptr);
/* Initialize all the virtual function table fields that
do not come from virtual base classes. */
expand_direct_vtbls_init (t_binfo, t_binfo, 1, 1, current_class_decl);
expand_direct_vtbls_init (t_binfo, t_binfo, 1, 1, current_class_ptr);
for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
{
......@@ -863,7 +863,7 @@ do_member_init (s_id, name, init)
return;
}
base = convert_pointer_to (binfo, current_class_decl);
base = convert_pointer_to (binfo, current_class_ptr);
expand_member_init (build_indirect_ref (base, NULL_PTR), name, init);
}
......@@ -1139,8 +1139,9 @@ expand_member_init (exp, name, init)
explaining that such initializations are invalid.
ALIAS_THIS is nonzero iff we are initializing something which is
essentially an alias for C_C_D. In this case, the base constructor
may move it on us, and we must keep track of such deviations.
essentially an alias for current_class_ref. In this case, the base
constructor may move it on us, and we must keep track of such
deviations.
If INIT resolves to a CALL_EXPR which happens to return
something of the type we are looking for, then we know
......@@ -1160,8 +1161,7 @@ expand_member_init (exp, name, init)
initialization.
A constructor or a conversion operator may have to be used to
perform the initialization, but not both, as it would be ambiguous.
*/
perform the initialization, but not both, as it would be ambiguous. */
void
expand_aggr_init (exp, init, alias_this, flags)
......@@ -1318,8 +1318,8 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags)
value is used in the derived class. */
if ((flag_this_is_variable & 1) && alias_this)
{
TREE_TYPE (rval) = TREE_TYPE (current_class_decl);
expand_assignment (current_class_decl, rval, 0, 0);
TREE_TYPE (rval) = TREE_TYPE (current_class_ptr);
expand_assignment (current_class_ptr, rval, 0, 0);
}
else
expand_expr_stmt (rval);
......@@ -1676,7 +1676,7 @@ build_member_call (type, name, parmlist)
tree ns = lookup_name (type, 0);
if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
{
return build_x_function_call (build_offset_ref (type, name), parmlist, current_class_decl);
return build_x_function_call (build_offset_ref (type, name), parmlist, current_class_ref);
}
}
......@@ -1705,14 +1705,14 @@ build_member_call (type, name, parmlist)
basetype_path = TYPE_BINFO (type);
decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
}
else if (current_class_decl == 0)
else if (current_class_ptr == 0)
{
dont_use_this = 1;
decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
}
else
{
tree olddecl = current_class_decl;
tree olddecl = current_class_ptr;
tree oldtype = TREE_TYPE (TREE_TYPE (olddecl));
if (oldtype != type)
{
......@@ -1846,10 +1846,10 @@ build_offset_ref (type, name)
basebinfo = TYPE_BINFO (type);
decl = build1 (NOP_EXPR, type, error_mark_node);
}
else if (current_class_decl == 0)
else if (current_class_ptr == 0)
decl = build1 (NOP_EXPR, type, error_mark_node);
else
decl = C_C_D;
decl = current_class_ref;
if (constructor_name (BINFO_TYPE (basebinfo)) == name)
if (dtor)
......@@ -1978,7 +1978,12 @@ resolve_offset_ref (exp)
if (TREE_CODE (exp) == TREE_LIST)
return build_unary_op (ADDR_EXPR, exp, 0);
if (TREE_CODE (exp) != OFFSET_REF)
if (TREE_CODE (exp) == OFFSET_REF)
{
member = TREE_OPERAND (exp, 1);
base = TREE_OPERAND (exp, 0);
}
else
{
my_friendly_assert (TREE_CODE (type) == OFFSET_TYPE, 214);
if (TYPE_OFFSET_BASETYPE (type) != current_class_type)
......@@ -1988,12 +1993,7 @@ resolve_offset_ref (exp)
}
member = exp;
type = TREE_TYPE (type);
base = C_C_D;
}
else
{
member = TREE_OPERAND (exp, 1);
base = TREE_OPERAND (exp, 0);
base = current_class_ref;
}
if ((TREE_CODE (member) == VAR_DECL
......@@ -2008,7 +2008,7 @@ resolve_offset_ref (exp)
/* Syntax error can cause a member which should
have been seen as static to be grok'd as non-static. */
if (TREE_CODE (member) == FIELD_DECL && C_C_D == NULL_TREE)
if (TREE_CODE (member) == FIELD_DECL && current_class_ref == NULL_TREE)
{
if (TREE_ADDRESSABLE (member) == 0)
{
......@@ -2022,7 +2022,7 @@ resolve_offset_ref (exp)
/* The first case is really just a reference to a member of `this'. */
if (TREE_CODE (member) == FIELD_DECL
&& (base == C_C_D
&& (base == current_class_ref
|| (TREE_CODE (base) == NOP_EXPR
&& TREE_OPERAND (base, 0) == error_mark_node)))
{
......@@ -2033,7 +2033,7 @@ resolve_offset_ref (exp)
else
basetype = DECL_CONTEXT (member);
base = current_class_decl;
base = current_class_ptr;
if (get_base_distance (basetype, TREE_TYPE (TREE_TYPE (base)), 0, &basetype_path) < 0)
{
......@@ -3555,8 +3555,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
addr = convert_force (build_pointer_type (type), addr, 0);
if (TREE_CODE (addr) == NOP_EXPR
&& TREE_OPERAND (addr, 0) == current_class_decl)
ref = C_C_D;
&& TREE_OPERAND (addr, 0) == current_class_ptr)
ref = current_class_ref;
else
ref = build_indirect_ref (addr, NULL_PTR);
ptr = 0;
......
......@@ -1549,19 +1549,19 @@ hack_identifier (value, name)
type = TREE_TYPE (value);
if (TREE_CODE (value) == FIELD_DECL)
{
if (current_class_decl == NULL_TREE)
if (current_class_ptr == NULL_TREE)
{
error ("request for member `%s' in static member function",
IDENTIFIER_POINTER (DECL_NAME (value)));
return error_mark_node;
}
TREE_USED (current_class_decl) = 1;
TREE_USED (current_class_ptr) = 1;
/* Mark so that if we are in a constructor, and then find that
this field was initialized by a base initializer,
we can emit an error message. */
TREE_USED (value) = 1;
value = build_component_ref (C_C_D, name, NULL_TREE, 1);
value = build_component_ref (current_class_ref, name, NULL_TREE, 1);
}
else if (really_overloaded_fn (value))
{
......@@ -1653,141 +1653,6 @@ hack_identifier (value, name)
}
#if 0
/* Given an object OF, and a type conversion operator COMPONENT
build a call to the conversion operator, if a call is requested,
or return the address (as a pointer to member function) if one is not.
OF can be a TYPE_DECL or any kind of datum that would normally
be passed to `build_component_ref'. It may also be NULL_TREE,
in which case `current_class_type' and `current_class_decl'
provide default values.
BASETYPE_PATH, if non-null, is the path of basetypes
to go through before we get the the instance of interest.
PROTECT says whether we apply C++ scoping rules or not. */
tree
build_component_type_expr (of, component, basetype_path, protect)
tree of, component, basetype_path;
int protect;
{
tree cname = NULL_TREE;
tree tmp, last;
tree name;
int flags = protect ? LOOKUP_NORMAL : LOOKUP_COMPLAIN;
if (of)
my_friendly_assert (IS_AGGR_TYPE (TREE_TYPE (of)), 253);
my_friendly_assert (TREE_CODE (component) == TYPE_EXPR, 254);
tmp = TREE_OPERAND (component, 0);
last = NULL_TREE;
while (tmp)
{
switch (TREE_CODE (tmp))
{
case CALL_EXPR:
if (last)
TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0);
else
TREE_OPERAND (component, 0) = TREE_OPERAND (tmp, 0);
last = groktypename (build_tree_list (TREE_TYPE (component),
TREE_OPERAND (component, 0)));
name = build_typename_overload (last);
TREE_TYPE (name) = last;
if (TREE_OPERAND (tmp, 0)
&& TREE_OPERAND (tmp, 0) != void_list_node)
{
cp_error ("`operator %T' requires empty parameter list", last);
TREE_OPERAND (tmp, 0) = NULL_TREE;
}
if (of && TREE_CODE (of) != TYPE_DECL)
return build_method_call (of, name, NULL_TREE, NULL_TREE, flags);
else if (of)
{
tree this_this;
if (current_class_decl == NULL_TREE)
{
cp_error ("object required for `operator %T' call",
TREE_TYPE (name));
return error_mark_node;
}
this_this = convert_pointer_to (TREE_TYPE (of),
current_class_decl);
this_this = build_indirect_ref (this_this, NULL_PTR);
return build_method_call (this_this, name, NULL_TREE,
NULL_TREE, flags | LOOKUP_NONVIRTUAL);
}
else if (current_class_decl)
return build_method_call (tmp, name, NULL_TREE, NULL_TREE, flags);
cp_error ("object required for `operator %T' call",
TREE_TYPE (name));
return error_mark_node;
case INDIRECT_REF:
case ADDR_EXPR:
case ARRAY_REF:
break;
case SCOPE_REF:
my_friendly_assert (cname == 0, 255);
cname = TREE_OPERAND (tmp, 0);
tmp = TREE_OPERAND (tmp, 1);
break;
default:
my_friendly_abort (77);
}
last = tmp;
tmp = TREE_OPERAND (tmp, 0);
}
last = groktypename (build_tree_list (TREE_TYPE (component), TREE_OPERAND (component, 0)));
name = build_typename_overload (last);
TREE_TYPE (name) = last;
if (of && TREE_CODE (of) == TYPE_DECL)
{
if (cname == NULL_TREE)
{
cname = DECL_NAME (of);
of = NULL_TREE;
}
else my_friendly_assert (cname == DECL_NAME (of), 256);
}
if (of)
{
tree this_this;
if (current_class_decl == NULL_TREE)
{
cp_error ("object required for `operator %T' call",
TREE_TYPE (name));
return error_mark_node;
}
this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl);
return build_component_ref (this_this, name, NULL_TREE, protect);
}
else if (cname)
return build_offset_ref (cname, name);
else if (current_class_name)
return build_offset_ref (current_class_name, name);
cp_error ("object required for `operator %T' member reference",
TREE_TYPE (name));
return error_mark_node;
}
#endif
static char *
thunk_printable_name (decl)
tree decl;
......@@ -1863,6 +1728,7 @@ emit_thunk (thunk_fndecl)
char *fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
int tem;
int failure = 0;
int save_ofp;
/* Used to remember which regs we need to emit a USE rtx for. */
rtx need_use[FIRST_PSEUDO_REGISTER];
......@@ -1892,6 +1758,8 @@ emit_thunk (thunk_fndecl)
ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function);
assemble_end_function (thunk_fndecl, fnname);
#else
save_ofp = flag_omit_frame_pointer;
flag_omit_frame_pointer = 1;
init_function_start (thunk_fndecl, input_filename, lineno);
pushlevel (0);
expand_start_bindings (1);
......@@ -2063,13 +1931,12 @@ emit_thunk (thunk_fndecl)
final (insns, asm_out_file, optimize, 0);
assemble_end_function (thunk_fndecl, fnname);
exit_rest_of_compilation:
reload_completed = 0;
/* Cancel the effect of rtl_in_current_obstack. */
permanent_allocation (1);
flag_omit_frame_pointer = save_ofp;
#endif /* ASM_OUTPUT_MI_THUNK */
decl_printable_name = save_decl_printable_name;
......@@ -2112,7 +1979,7 @@ do_build_copy_constructor (fndecl)
if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type))
{
t = build (INIT_EXPR, void_type_node, C_C_D, parm);
t = build (INIT_EXPR, void_type_node, current_class_ref, parm);
TREE_SIDE_EFFECTS (t) = 1;
cplus_expand_expr_stmt (t);
}
......@@ -2202,7 +2069,7 @@ do_build_assign_ref (fndecl)
if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type))
{
tree t = build (MODIFY_EXPR, void_type_node, C_C_D, parm);
tree t = build (MODIFY_EXPR, void_type_node, current_class_ref, parm);
TREE_SIDE_EFFECTS (t) = 1;
cplus_expand_expr_stmt (t);
}
......@@ -2253,13 +2120,13 @@ do_build_assign_ref (fndecl)
else
continue;
comp = build (COMPONENT_REF, TREE_TYPE (field), C_C_D, field);
comp = build (COMPONENT_REF, TREE_TYPE (field), current_class_ref, field);
init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
}
}
c_expand_return (C_C_D);
c_expand_return (current_class_ref);
pop_momentary ();
}
......
......@@ -782,22 +782,22 @@ member_init: '(' nonnull_exprlist ')'
{
if (current_class_name && !flag_traditional)
pedwarn ("anachronistic old style base class initializer");
expand_member_init (C_C_D, NULL_TREE, $2);
expand_member_init (current_class_ref, NULL_TREE, $2);
}
| LEFT_RIGHT
{
if (current_class_name && !flag_traditional)
pedwarn ("anachronistic old style base class initializer");
expand_member_init (C_C_D, NULL_TREE, void_type_node);
expand_member_init (current_class_ref, NULL_TREE, void_type_node);
}
| notype_identifier '(' nonnull_exprlist ')'
{ expand_member_init (C_C_D, $1, $3); }
{ expand_member_init (current_class_ref, $1, $3); }
| notype_identifier LEFT_RIGHT
{ expand_member_init (C_C_D, $1, void_type_node); }
{ expand_member_init (current_class_ref, $1, void_type_node); }
| complete_type_name '(' nonnull_exprlist ')'
{ expand_member_init (C_C_D, $1, $3); }
{ expand_member_init (current_class_ref, $1, $3); }
| complete_type_name LEFT_RIGHT
{ expand_member_init (C_C_D, $1, void_type_node); }
{ expand_member_init (current_class_ref, $1, void_type_node); }
/* GNU extension */
| notype_qualified_id '(' nonnull_exprlist ')'
{
......@@ -1046,12 +1046,7 @@ nonnull_exprlist:
unary_expr:
primary %prec UNARY
{
#if 0
if (TREE_CODE ($$) == TYPE_EXPR)
$$ = build_component_type_expr (C_C_D, $$, NULL_TREE, 1);
#endif
}
{ $$ = $1; }
/* __extension__ turns off -pedantic for following primary. */
| EXTENSION
{ $<itype>1 = pedantic;
......@@ -1362,14 +1357,14 @@ primary:
}
| primary '(' nonnull_exprlist ')'
{
$$ = build_x_function_call ($1, $3, current_class_decl);
$$ = build_x_function_call ($1, $3, current_class_ref);
if (TREE_CODE ($$) == CALL_EXPR
&& TREE_TYPE ($$) != void_type_node)
$$ = require_complete_type ($$);
}
| primary LEFT_RIGHT
{
$$ = build_x_function_call ($$, NULL_TREE, current_class_decl);
$$ = build_x_function_call ($$, NULL_TREE, current_class_ref);
if (TREE_CODE ($$) == CALL_EXPR
&& TREE_TYPE ($$) != void_type_node)
$$ = require_complete_type ($$);
......@@ -1391,12 +1386,12 @@ primary:
$$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); }
/* C++ extensions */
| THIS
{ if (current_class_decl)
{ if (current_class_ptr)
{
#ifdef WARNING_ABOUT_CCD
TREE_USED (current_class_decl) = 1;
TREE_USED (current_class_ptr) = 1;
#endif
$$ = current_class_decl;
$$ = current_class_ptr;
}
else if (current_function_decl
&& DECL_STATIC_FUNCTION_P (current_function_decl))
......@@ -1516,13 +1511,13 @@ primary:
/* This is a future direction of this code, but because
build_x_function_call cannot always undo what is done
in build_component_ref entirely yet, we cannot do this. */
$$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), $4, $$);
$$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), $4, current_class_ref);
if (TREE_CODE ($$) == CALL_EXPR
&& TREE_TYPE ($$) != void_type_node)
$$ = require_complete_type ($$);
#else
$$ = build_method_call ($$, $2, $4, NULL_TREE,
(LOOKUP_NORMAL|LOOKUP_AGGR));
LOOKUP_NORMAL);
#endif
}
| object unqualified_id LEFT_RIGHT
......@@ -1531,13 +1526,13 @@ primary:
/* This is a future direction of this code, but because
build_x_function_call cannot always undo what is done
in build_component_ref entirely yet, we cannot do this. */
$$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), NULL_TREE, $$);
$$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), NULL_TREE, current_class_ref);
if (TREE_CODE ($$) == CALL_EXPR
&& TREE_TYPE ($$) != void_type_node)
$$ = require_complete_type ($$);
#else
$$ = build_method_call ($$, $2, NULL_TREE, NULL_TREE,
(LOOKUP_NORMAL|LOOKUP_AGGR));
LOOKUP_NORMAL);
#endif
}
| object overqualified_id '(' nonnull_exprlist ')'
......@@ -1546,7 +1541,7 @@ primary:
{
warning ("signature name in scope resolution ignored");
$$ = build_method_call ($$, OP1 ($2), $4, NULL_TREE,
(LOOKUP_NORMAL|LOOKUP_AGGR));
LOOKUP_NORMAL);
}
else
$$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), $4);
......@@ -1557,7 +1552,7 @@ primary:
{
warning ("signature name in scope resolution ignored");
$$ = build_method_call ($$, OP1 ($2), NULL_TREE, NULL_TREE,
(LOOKUP_NORMAL|LOOKUP_AGGR));
LOOKUP_NORMAL);
}
else
$$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), NULL_TREE);
......@@ -1605,9 +1600,9 @@ primary_no_id:
pedwarn ("ANSI C++ forbids braced-groups within expressions");
$$ = expand_end_stmt_expr ($<ttype>2); }
| primary_no_id '(' nonnull_exprlist ')'
{ $$ = build_x_function_call ($$, $3, current_class_decl); }
{ $$ = build_x_function_call ($$, $3, current_class_ref); }
| primary_no_id LEFT_RIGHT
{ $$ = build_x_function_call ($$, NULL_TREE, current_class_decl); }
{ $$ = build_x_function_call ($$, NULL_TREE, current_class_ref); }
| primary_no_id '[' expr ']'
{ goto do_array; }
| primary_no_id PLUSPLUS
......
......@@ -2581,6 +2581,10 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
return 0;
case POINTER_TYPE:
if (TREE_CODE (arg) == RECORD_TYPE && TYPE_PTRMEMFUNC_FLAG (arg))
return unify (tparms, targs, ntparms, parm,
TYPE_PTRMEMFUNC_FN_TYPE (arg), nsubsts);
if (TREE_CODE (arg) != POINTER_TYPE)
return 1;
return unify (tparms, targs, ntparms, TREE_TYPE (parm), TREE_TYPE (arg),
......
......@@ -769,7 +769,7 @@ lookup_field_1 (type, name)
itself inside a class, we need decls to go into the fn's decls (our
second case below). But if we're in a class and the class itself is
inside a function, we need decls to go into the decls for the class. To
achieve this last goal, we must see if, when both current_class_decl and
achieve this last goal, we must see if, when both current_class_ptr and
current_function_decl are set, the class was declared inside that
function. If so, we know to put the decls into the class's scope. */
......
......@@ -573,7 +573,7 @@ build_signature_table_constructor (sig_ty, rhs)
vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
delta = integer_zero_node;
index = integer_zero_node;
pfn = build_unary_op (ADDR_EXPR, rhs_method, 0);
pfn = build_addr_func (rhs_method);
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (rhs_method)) = 1;
TREE_TYPE (pfn) = ptr_type_node;
TREE_ADDRESSABLE (rhs_method) = 1;
......@@ -584,8 +584,12 @@ build_signature_table_constructor (sig_ty, rhs)
/* virtual member function */
tag = integer_one_node;
vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method),
rhstype, 1));
if (flag_vtable_thunks)
delta = BINFO_OFFSET
(get_binfo (DECL_CONTEXT (rhs_method), rhstype, 1));
else
delta = BINFO_OFFSET
(get_binfo (DECL_CLASS_CONTEXT (rhs_method), rhstype, 1));
index = DECL_VINDEX (rhs_method);
vt_off = get_vfield_offset (get_binfo (DECL_CONTEXT (rhs_method),
rhstype, 0));
......@@ -598,7 +602,7 @@ build_signature_table_constructor (sig_ty, rhs)
delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method),
rhstype, 1));
index = integer_zero_node;
pfn = build_unary_op (ADDR_EXPR, rhs_method, 0);
pfn = build_addr_func (rhs_method);
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (rhs_method)) = 1;
TREE_TYPE (pfn) = ptr_type_node;
TREE_ADDRESSABLE (rhs_method) = 1;
......@@ -985,10 +989,7 @@ build_signature_method_call (basetype, instance, function, parms)
TREE_TYPE (vfn) = build_pointer_type (TREE_TYPE (function));
if (flag_vtable_thunks)
virtual_call = build_function_call (vfn, parms);
else
virtual_call = build_function_call (vfn, new_parms);
virtual_call = build_function_call (vfn, new_parms);
}
/* Undo the cast, make `this' a signature pointer again. */
......
......@@ -48,7 +48,7 @@ real_lvalue_p (ref)
if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
return 1;
if (ref == current_class_decl && flag_this_is_variable <= 0)
if (ref == current_class_ptr && flag_this_is_variable <= 0)
return 0;
switch (TREE_CODE (ref))
......@@ -118,7 +118,7 @@ lvalue_p (ref)
if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
return 1;
if (ref == current_class_decl && flag_this_is_variable <= 0)
if (ref == current_class_ptr && flag_this_is_variable <= 0)
return 0;
switch (TREE_CODE (ref))
......
......@@ -1341,7 +1341,7 @@ build_m_component_ref (datum, component)
{
component = build_indirect_ref (component, NULL_PTR);
type = TREE_TYPE (component);
rettype = TREE_TYPE (TREE_TYPE (component));
rettype = TREE_TYPE (type);
}
if (datum == error_mark_node || component == error_mark_node)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment