#include "toplev.h"
#include "defaults.h"
#include "expr.h"
-
-#include "obstack.h"
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
+#include "ggc.h"
extern int inhibit_warnings;
{
tree field, instance;
- if (name == ctor_identifier || name == dtor_identifier)
+ if (IDENTIFIER_CTOR_OR_DTOR_P (name))
return NULL_TREE;
/* Speed up the common case. */
if (TREE_CODE (name) == TYPE_DECL)
name = TREE_TYPE (name);
- else if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
+ else if (TYPE_P (name))
/* OK */;
else if (TREE_CODE (name) == IDENTIFIER_NODE)
{
tree fn, convs;
int viable;
{
- /* FIXME: This is a memory leak. Presumably, we should use
- ggc_alloc instead. */
struct z_candidate *cand
- = (struct z_candidate *) expralloc (sizeof (struct z_candidate));
+ = (struct z_candidate *) ggc_alloc_obj (sizeof (struct z_candidate), 1);
cand->fn = fn;
cand->convs = convs;
- cand->second_conv = NULL_TREE;
cand->viable = viable;
- cand->basetype_path = NULL_TREE;
- cand->template = NULL_TREE;
- cand->warnings = NULL_TREE;
cand->next = candidates;
return cand;
{
parmlist = TREE_CHAIN (parmlist);
arglist = TREE_CHAIN (arglist);
- if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
+ if (DECL_HAS_IN_CHARGE_PARM_P (fn))
{
parmlist = TREE_CHAIN (parmlist);
arglist = TREE_CHAIN (arglist);
is_complete (t)
tree t;
{
- return TYPE_SIZE (complete_type (t)) != NULL_TREE;
+ return COMPLETE_TYPE_P (complete_type (t));
}
/* Returns non-zero if TYPE is a promoted arithmetic type. */
tree templates = NULL_TREE;
if (IS_AGGR_TYPE (totype))
- ctors = lookup_fnfields (TYPE_BINFO (totype), ctor_identifier, 0);
+ ctors = lookup_fnfields (TYPE_BINFO (totype),
+ (flag_new_abi
+ ? complete_ctor_identifier
+ : ctor_identifier),
+ 0);
+
if (IS_AGGR_TYPE (fromtype)
&& (! IS_AGGR_TYPE (totype) || ! DERIVED_FROM_P (totype, fromtype)))
convs = lookup_conversions (fromtype);
if (ctors)
{
- tree t = build_int_2 (0, 0);
+ tree t;
+
+ ctors = TREE_VALUE (ctors);
+
+ t = build_int_2 (0, 0);
TREE_TYPE (t) = build_pointer_type (totype);
args = build_tree_list (NULL_TREE, expr);
- if (TYPE_USES_VIRTUAL_BASECLASSES (totype))
+ if (DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors)))
args = tree_cons (NULL_TREE, integer_one_node, args);
args = tree_cons (NULL_TREE, t, args);
-
- ctors = TREE_VALUE (ctors);
}
for (; ctors; ctors = OVL_NEXT (ctors))
{
TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (fn));
args = build_tree_list (NULL_TREE, expr);
- if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
+ if (DECL_HAS_IN_CHARGE_PARM_P (fn))
args = tree_cons (NULL_TREE, integer_one_node, args);
args = tree_cons (NULL_TREE, t, args);
}
conversion because the type might be an incomplete
array type, which is OK if some constructor for the
destination type takes a pointer argument. */
- if (TYPE_SIZE (TREE_TYPE (expr)) == 0)
+ if (!COMPLETE_TYPE_P (TREE_TYPE (expr)))
{
if (same_type_p (TREE_TYPE (expr), TREE_TYPE (convs)))
incomplete_type_error (expr, TREE_TYPE (expr));
converted_args = tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args);
arg = TREE_CHAIN (arg);
parm = TREE_CHAIN (parm);
- if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
+ if (DECL_HAS_IN_CHARGE_PARM_P (fn))
{
converted_args = tree_cons
(NULL_TREE, TREE_VALUE (arg), converted_args);
if (! flag_elide_constructors)
/* Do things the hard way. */;
- else if (DECL_CONSTRUCTOR_P (fn)
- && TREE_VEC_LENGTH (convs) == 1
- && copy_args_p (fn))
+ else if (TREE_VEC_LENGTH (convs) == 1
+ && DECL_COPY_CONSTRUCTOR_P (fn))
{
tree targ;
arg = TREE_CHAIN (converted_args);
- if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
+ if (DECL_HAS_IN_CHARGE_PARM_P (fn))
arg = TREE_CHAIN (arg);
arg = TREE_VALUE (arg);
return convert_from_reference (fn);
}
+/* Returns the value to use for the in-charge parameter when making a
+ call to a function with the indicated NAME. */
+
+tree
+in_charge_arg_for_name (name)
+ tree name;
+{
+ if (name == base_ctor_identifier
+ || name == base_dtor_identifier)
+ return integer_zero_node;
+ else if (name == complete_ctor_identifier)
+ return integer_one_node;
+ else if (name == complete_dtor_identifier)
+ return integer_two_node;
+ else if (name == deleting_dtor_identifier)
+ return integer_three_node;
+
+ /* This function should only be called with one of the names listed
+ above. */
+ my_friendly_abort (20000411);
+ return NULL_TREE;
+}
+
static tree
build_new_method_call (instance, name, args, basetype_path, flags)
tree instance, name, args, basetype_path;
{
explicit_targs = TREE_OPERAND (name, 1);
name = TREE_OPERAND (name, 0);
- if (TREE_CODE_CLASS (TREE_CODE (name)) == 'd')
+ if (DECL_P (name))
name = DECL_NAME (name);
else
{
template_only = 1;
}
- /* If there is an extra argument for controlling virtual bases,
- remove it for error reporting. */
- if (flags & LOOKUP_HAS_IN_CHARGE)
- user_args = TREE_CHAIN (args);
-
+ user_args = args;
args = resolve_args (args);
if (args == error_mark_node)
TREE_TYPE (instance_ptr) = build_pointer_type (basetype);
}
- pretty_name
- = (name == ctor_identifier ? constructor_name (basetype) : name);
+ /* Callers should explicitly indicate whether they want to construct
+ the complete object or just the part without virtual bases. */
+ my_friendly_assert (name != ctor_identifier, 20000408);
+ /* Similarly for destructors. */
+ my_friendly_assert (name != dtor_identifier, 20000408);
+
+ if (IDENTIFIER_CTOR_OR_DTOR_P (name))
+ {
+ int constructor_p;
+
+ constructor_p = (name == complete_ctor_identifier
+ || name == base_ctor_identifier);
+ pretty_name = (constructor_p
+ ? constructor_name (basetype) : dtor_identifier);
+
+ if (!flag_new_abi)
+ {
+ /* Add the in-charge parameter as an implicit first argument. */
+ if (!constructor_p
+ || TYPE_USES_VIRTUAL_BASECLASSES (basetype))
+ args = tree_cons (NULL_TREE,
+ in_charge_arg_for_name (name),
+ args);
+
+ /* We want to call the normal constructor function under the
+ old ABI. */
+ name = constructor_p ? ctor_identifier : dtor_identifier;
+ }
+ }
+ else
+ pretty_name = name;
fns = lookup_fnfields (basetype_path, name, 1);
{
tree base = BINFO_TYPE (TREE_PURPOSE (fns));
tree fn = TREE_VALUE (fns);
- if (name == ctor_identifier && TYPE_USES_VIRTUAL_BASECLASSES (basetype)
- && ! (flags & LOOKUP_HAS_IN_CHARGE))
- {
- flags |= LOOKUP_HAS_IN_CHARGE;
- args = tree_cons (NULL_TREE, integer_one_node, args);
- }
mem_args = tree_cons (NULL_TREE, instance_ptr, args);
for (; fn; fn = OVL_NEXT (fn))
{
tree this_arglist;
/* We can end up here for copy-init of same or base class. */
- if (name == ctor_identifier
- && (flags & LOOKUP_ONLYCONVERTING)
+ if ((flags & LOOKUP_ONLYCONVERTING)
&& DECL_NONCONVERTING_P (t))
continue;
if (TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE)
/* XXX will LOOKUP_SPECULATIVELY be needed when this is done? */
if (flags & LOOKUP_SPECULATIVELY)
return NULL_TREE;
- if (TYPE_SIZE (basetype) == 0)
+ if (!COMPLETE_TYPE_P (basetype))
incomplete_type_error (instance_ptr, basetype);
else
cp_error ("no matching function for call to `%T::%D (%A)%V'",