* vec.h (VEC_address): New function.
* cp-tree.h (lang_type_class): Remove has_real_assign_ref and
has_abstract_assign_ref. Make methods a VEC(tree) *.
(TYPE_HAS_CONST_ASSIGN_REF): Add documentation.
(CLASSTYPE_CONSTRUCTORS): Adjust for changes to CLASSTYPE_METHOD_VEC.
(CLASSTYPE_DESTRUCTORS): Likewise.
(TYPE_HAS_REAL_ASSIGN_REF): Remove.
(TYPE_HAS_ABSTRACT_ASSIGN_REF): Likewise.
(add_method): Change prototoype.
* class.c (add_method): Remove error_p parameter. Adjust for
changes to CLASSTYPE_METHOD_VEC.
(handle_using_decl): Adjust call to add_method.
(maybe_warn_about_overly_private_class): Adjust for
changes to CLASSTYPE_METHOD_VEC.
(resort_type_method_vec): Likewise.
(finish_struct_methods): Likewise.
(check_for_override): Likewise.
(warn_hidden): Likewise.
(add_implicitly_declared_members): Defer creation of assignment
operators. Adjust call to add_method.
(clone_function_decl): Adjust call to add_method.
(check_bases_and_members): Don't set TYPE_HAS_REAL_ASSIGN_REF.
(finish_struct_1): Use CLASSTYPE_DESTRUCTORS.
* decl.c (grok_special_member_properties): Don't set
TYPE_HAS_ABSTRACT_ASSIGN_REF.
* decl2.c (check_classfn): Adjust for
changes to CLASSTYPE_METHOD_VEC.
* method.c (locate_dtor): Use CLASSTYPE_DESTRUCTORS.
(locate_ctor): Use CLASSTYPE_CONSTRUCTORS.
(locate_copy): Adjust for changes to CLASSTYPE_METHOD_VEC.
(implicitly_declare_fn): Set DECL_SOURCE_LOCATION. Do not call
cp_finish_decl.
* pt.c (check_explicit_specialization): Adjust for
changes to CLASSTYPE_METHOD_VEC.
(instantiate_class_template): Do not set
TYPE_HAS_ABSTRACT_ASSIGN_REF.
* ptree.c (cxx_print_type): Don't try to print
CLASSTYPE_METHOD_VEC.
* rtti.c (emit_support_tinfos): Use CLASSTYPE_DESTRUCTORS.
* search.c (lookup_field_r): Adjust for
changes to CLASSTYPE_METHOD_VEC.
(lookup_fnfields): Likewise.
(lookup_conversion_operator): Likewise.
(lookup_fnfields_1): Likewise. Create assignment operators
lazily.
(look_for_overrides_here): Adjust for
changes to CLASSTYPE_METHOD_VEC.
(add_conversions): Likewise.
* semantics.c (finish_member_declaration): Adjust call to add_method.
From-SVN: r84796
+2004-07-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.h (VEC_address): New function.
+
2004-07-14 Jason Merrill <jason@redhat.com>
PR middle-end/15885
+2004-07-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_type_class): Remove has_real_assign_ref and
+ has_abstract_assign_ref. Make methods a VEC(tree) *.
+ (TYPE_HAS_CONST_ASSIGN_REF): Add documentation.
+ (CLASSTYPE_CONSTRUCTORS): Adjust for changes to CLASSTYPE_METHOD_VEC.
+ (CLASSTYPE_DESTRUCTORS): Likewise.
+ (TYPE_HAS_REAL_ASSIGN_REF): Remove.
+ (TYPE_HAS_ABSTRACT_ASSIGN_REF): Likewise.
+ (add_method): Change prototoype.
+ * class.c (add_method): Remove error_p parameter. Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ (handle_using_decl): Adjust call to add_method.
+ (maybe_warn_about_overly_private_class): Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ (resort_type_method_vec): Likewise.
+ (finish_struct_methods): Likewise.
+ (check_for_override): Likewise.
+ (warn_hidden): Likewise.
+ (add_implicitly_declared_members): Defer creation of assignment
+ operators. Adjust call to add_method.
+ (clone_function_decl): Adjust call to add_method.
+ (check_bases_and_members): Don't set TYPE_HAS_REAL_ASSIGN_REF.
+ (finish_struct_1): Use CLASSTYPE_DESTRUCTORS.
+ * decl.c (grok_special_member_properties): Don't set
+ TYPE_HAS_ABSTRACT_ASSIGN_REF.
+ * decl2.c (check_classfn): Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ * method.c (locate_dtor): Use CLASSTYPE_DESTRUCTORS.
+ (locate_ctor): Use CLASSTYPE_CONSTRUCTORS.
+ (locate_copy): Adjust for changes to CLASSTYPE_METHOD_VEC.
+ (implicitly_declare_fn): Set DECL_SOURCE_LOCATION. Do not call
+ cp_finish_decl.
+ * pt.c (check_explicit_specialization): Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ (instantiate_class_template): Do not set
+ TYPE_HAS_ABSTRACT_ASSIGN_REF.
+ * ptree.c (cxx_print_type): Don't try to print
+ CLASSTYPE_METHOD_VEC.
+ * rtti.c (emit_support_tinfos): Use CLASSTYPE_DESTRUCTORS.
+ * search.c (lookup_field_r): Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ (lookup_fnfields): Likewise.
+ (lookup_conversion_operator): Likewise.
+ (lookup_fnfields_1): Likewise. Create assignment operators
+ lazily.
+ (look_for_overrides_here): Adjust for
+ changes to CLASSTYPE_METHOD_VEC.
+ (add_conversions): Likewise.
+ * semantics.c (finish_member_declaration): Adjust call to add_method.
+
2004-07-15 Jason Merrill <jason@redhat.com>
* cp-lang.c (cxx_types_compatible_p): To the middle-end,
(copy_binfo): Declare.
2004-07-15 Mark Mitchell <mark@codesourcery.com>
-
+
* name-lookup.c (set_inherited_value_binding_p): Add class_type
parameter.
(get_class_binding): Adjust.
}
\f
-/* Add method METHOD to class TYPE. If ERROR_P is true, we are adding
- the method after the class has already been defined because a
- declaration for it was seen. (Even though that is erroneous, we
- add the method for improved error recovery.) */
+/* Add method METHOD to class TYPE. */
void
-add_method (tree type, tree method, int error_p)
+add_method (tree type, tree method)
{
int using;
- int len;
- int slot;
- tree method_vec;
+ size_t len;
+ size_t slot;
tree overload;
int template_conv_p;
+ VEC(tree) *method_vec;
+ bool complete_p;
if (method == error_mark_node)
return;
-
+
+ complete_p = COMPLETE_TYPE_P (type);
using = (DECL_CONTEXT (method) != type);
template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
&& DECL_TEMPLATE_CONV_FN_P (method));
- if (!CLASSTYPE_METHOD_VEC (type))
- /* Make a new method vector. We start with 8 entries. We must
- allocate at least two (for constructors and destructors), and
- we're going to end up with an assignment operator at some point
- as well.
-
- We could use a TREE_LIST for now, and convert it to a TREE_VEC
- in finish_struct, but we would probably waste more memory
- making the links in the list than we would by over-allocating
- the size of the vector here. Furthermore, we would complicate
- all the code that expects this to be a vector. */
- CLASSTYPE_METHOD_VEC (type) = make_tree_vec (8);
-
method_vec = CLASSTYPE_METHOD_VEC (type);
- len = TREE_VEC_LENGTH (method_vec);
+ if (!method_vec)
+ {
+ /* Make a new method vector. We start with 8 entries. We must
+ allocate at least two (for constructors and destructors), and
+ we're going to end up with an assignment operator at some
+ point as well. */
+ method_vec = VEC_alloc (tree, 8);
+ /* Create slots for constructors and destructors. */
+ VEC_quick_push (tree, method_vec, NULL_TREE);
+ VEC_quick_push (tree, method_vec, NULL_TREE);
+ CLASSTYPE_METHOD_VEC (type) = method_vec;
+ }
+
+ len = VEC_length (tree, method_vec);
/* Constructors and destructors go in special slots. */
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (method))
}
else
{
- int have_template_convs_p = 0;
-
+ bool insert_p = true;
+ bool conv_p = DECL_CONV_FN_P (method);
+ tree m;
+
/* See if we already have an entry with this name. */
- for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; slot < len; ++slot)
+ for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ (m = VEC_iterate (tree, method_vec, slot));
+ ++slot)
{
- tree m = TREE_VEC_ELT (method_vec, slot);
-
- if (!m)
- break;
m = OVL_CURRENT (m);
-
if (template_conv_p)
{
- have_template_convs_p = (TREE_CODE (m) == TEMPLATE_DECL
- && DECL_TEMPLATE_CONV_FN_P (m));
-
- /* If we need to move things up, see if there's
- space. */
- if (!have_template_convs_p)
- {
- slot = len - 1;
- if (TREE_VEC_ELT (method_vec, slot))
- slot++;
- }
+ if (TREE_CODE (m) == TEMPLATE_DECL
+ && DECL_TEMPLATE_CONV_FN_P (m))
+ insert_p = false;
break;
}
- if (DECL_NAME (m) == DECL_NAME (method))
+ if (conv_p && !DECL_CONV_FN_P (m))
break;
- }
-
- if (slot == len)
- {
- /* We need a bigger method vector. */
- int new_len;
- tree new_vec;
-
- /* In the non-error case, we are processing a class
- definition. Double the size of the vector to give room
- for new methods. */
- if (!error_p)
- new_len = 2 * len;
- /* In the error case, the vector is already complete. We
- don't expect many errors, and the rest of the front-end
- will get confused if there are empty slots in the vector. */
- else
- new_len = len + 1;
-
- new_vec = make_tree_vec (new_len);
- memcpy (&TREE_VEC_ELT (new_vec, 0), &TREE_VEC_ELT (method_vec, 0),
- len * sizeof (tree));
- len = new_len;
- method_vec = CLASSTYPE_METHOD_VEC (type) = new_vec;
- }
-
- if (DECL_CONV_FN_P (method) && !TREE_VEC_ELT (method_vec, slot))
- {
- /* Type conversion operators have to come before ordinary
- methods; add_conversions depends on this to speed up
- looking for conversion operators. So, if necessary, we
- slide some of the vector elements up. In theory, this
- makes this algorithm O(N^2) but we don't expect many
- conversion operators. */
- if (template_conv_p)
- slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
- else
- for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; slot < len; ++slot)
- {
- tree fn = TREE_VEC_ELT (method_vec, slot);
-
- if (!fn)
- /* There are no more entries in the vector, so we
- can insert the new conversion operator here. */
- break;
-
- if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
- /* We can insert the new function right at the
- SLOTth position. */
- break;
- }
-
- if (template_conv_p && have_template_convs_p)
- /*OK*/;
- else if (!TREE_VEC_ELT (method_vec, slot))
- /* There is nothing in the Ith slot, so we can avoid
- moving anything. */
- ;
- else
+ if (DECL_NAME (m) == DECL_NAME (method))
{
- /* We know the last slot in the vector is empty
- because we know that at this point there's room
- for a new function. */
- memmove (&TREE_VEC_ELT (method_vec, slot + 1),
- &TREE_VEC_ELT (method_vec, slot),
- (len - slot - 1) * sizeof (tree));
- TREE_VEC_ELT (method_vec, slot) = NULL_TREE;
+ insert_p = false;
+ break;
}
+ if (complete_p
+ && !DECL_CONV_FN_P (m)
+ && DECL_NAME (m) > DECL_NAME (method))
+ break;
}
+
+ /* If we need a new slot, make room. */
+ if (insert_p)
+ {
+ /* We expect to add few methods in the COMPLETE_P case, so
+ just make room for one more method. */
+ if (complete_p)
+ VEC_reserve (tree, method_vec, 1);
+ if (slot == len)
+ VEC_safe_push (tree, method_vec, NULL_TREE);
+ else
+ VEC_safe_insert (tree, method_vec, slot, NULL_TREE);
+ len++;
+ /* Inserting a new slot may have caused the vector to be
+ reallocated. */
+ CLASSTYPE_METHOD_VEC (type) = method_vec;
+ }
}
if (processing_template_decl)
tree fns;
/* Check to see if we've already got this method. */
- for (fns = TREE_VEC_ELT (method_vec, slot);
+ for (fns = VEC_index (tree, method_vec, slot);
fns;
fns = OVL_NEXT (fns))
{
}
/* Add the new binding. */
- overload = build_overload (method, TREE_VEC_ELT (method_vec, slot));
+ overload = build_overload (method, VEC_index (tree, method_vec, slot));
if (!DECL_CONSTRUCTOR_P (method)
- && !DECL_DESTRUCTOR_P (method))
+ && !DECL_DESTRUCTOR_P (method)
+ && !complete_p)
push_class_level_binding (DECL_NAME (method), overload);
/* Actually insert the new method. */
- TREE_VEC_ELT (method_vec, slot) = overload;
+ VEC_replace (tree, method_vec, slot, overload);
}
/* Subroutines of finish_struct. */
if (flist)
for (; flist; flist = OVL_NEXT (flist))
{
- add_method (t, OVL_CURRENT (flist), /*error_p=*/0);
+ add_method (t, OVL_CURRENT (flist));
alter_access (t, OVL_CURRENT (flist), access);
}
else
if (!TYPE_HAS_INIT_REF (t))
nonprivate_ctor = 1;
else
- for (fn = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
- fn;
- fn = OVL_NEXT (fn))
+ for (fn = CLASSTYPE_CONSTRUCTORS (t); fn; fn = OVL_NEXT (fn))
{
tree ctor = OVL_CURRENT (fn);
/* Ideally, we wouldn't count copy constructors (or, in
gt_pointer_operator new_value,
void* cookie)
{
- tree method_vec = obj;
- int len = TREE_VEC_LENGTH (method_vec);
- int slot;
+ VEC(tree) *method_vec = (VEC(tree) *) obj;
+ int len = VEC_length (tree, method_vec);
+ size_t slot;
+ tree fn;
/* The type conversion ops have to live at the front of the vec, so we
can't sort them. */
- for (slot = 2; slot < len; ++slot)
- {
- tree fn = TREE_VEC_ELT (method_vec, slot);
-
- if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
- break;
- }
+ for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ (fn = VEC_iterate (tree, method_vec, slot));
+ ++slot)
+ if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
+ break;
+
if (len - slot > 1)
{
resort_data.new_value = new_value;
resort_data.cookie = cookie;
- qsort (&TREE_VEC_ELT (method_vec, slot), len - slot, sizeof (tree),
+ qsort (VEC_address (tree, method_vec) + slot, len - slot, sizeof (tree),
resort_method_name_cmp);
}
}
finish_struct_methods (tree t)
{
tree fn_fields;
- tree method_vec;
+ VEC(tree) *method_vec;
int slot, len;
if (!TYPE_METHODS (t))
these incorrectly. */
TYPE_HAS_CONSTRUCTOR (t) = 0;
TYPE_HAS_DESTRUCTOR (t) = 0;
- CLASSTYPE_METHOD_VEC (t) = NULL_TREE;
+ CLASSTYPE_METHOD_VEC (t) = NULL;
return;
}
method_vec = CLASSTYPE_METHOD_VEC (t);
- my_friendly_assert (method_vec != NULL_TREE, 19991215);
- len = TREE_VEC_LENGTH (method_vec);
+ my_friendly_assert (method_vec, 19991215);
+ len = VEC_length (tree, method_vec);
/* First fill in entry 0 with the constructors, entry 1 with destructors,
and the next few with type conversion operators (if any). */
no methods, then some public defaults are generated. */
maybe_warn_about_overly_private_class (t);
- /* Now sort the methods. */
- while (len > 2 && TREE_VEC_ELT (method_vec, len-1) == NULL_TREE)
- len--;
- TREE_VEC_LENGTH (method_vec) = len;
-
/* The type conversion ops have to live at the front of the vec, so we
can't sort them. */
- for (slot = 2; slot < len; ++slot)
- {
- tree fn = TREE_VEC_ELT (method_vec, slot);
-
- if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
- break;
- }
+ for (slot = 2;
+ (fn_fields = VEC_iterate (tree, method_vec, slot));
+ ++slot)
+ if (!DECL_CONV_FN_P (OVL_CURRENT (fn_fields)))
+ break;
if (len - slot > 1)
- qsort (&TREE_VEC_ELT (method_vec, slot), len-slot, sizeof (tree),
- method_name_cmp);
+ qsort (VEC_address (tree, method_vec) + slot,
+ len-slot, sizeof (tree), method_name_cmp);
}
/* Make BINFO's vtable have N entries, including RTTI entries,
/* Find virtual functions in T with the indicated NAME. */
i = lookup_fnfields_1 (t, name);
if (i != -1)
- for (methods = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), i);
+ for (methods = VEC_index (tree, CLASSTYPE_METHOD_VEC (t), i);
methods;
methods = OVL_NEXT (methods))
{
void
warn_hidden (tree t)
{
- tree method_vec = CLASSTYPE_METHOD_VEC (t);
- int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
- int i;
+ VEC(tree) *method_vec = CLASSTYPE_METHOD_VEC (t);
+ tree fns;
+ size_t i;
/* We go through each separately named virtual function. */
- for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); ++i)
+ for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ (fns = VEC_iterate (tree, method_vec, i));
+ ++i)
{
- tree fns;
+ tree fn;
tree name;
tree fndecl;
tree base_fndecls;
/* All functions in this slot in the CLASSTYPE_METHOD_VEC will
have the same name. Figure out what name that is. */
- name = DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
+ name = DECL_NAME (OVL_CURRENT (fns));
/* There are no possibly hidden functions yet. */
base_fndecls = NULL_TREE;
/* Iterate through all of the base classes looking for possibly
continue;
/* Remove any overridden functions. */
- for (fns = TREE_VEC_ELT (method_vec, i); fns; fns = OVL_NEXT (fns))
+ for (fn = fns; fn; fn = OVL_NEXT (fn))
{
- fndecl = OVL_CURRENT (fns);
+ fndecl = OVL_CURRENT (fn);
if (DECL_VINDEX (fndecl))
{
tree *prev = &base_fndecls;
{
/* Here we know it is a hider, and no overrider exists. */
cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls));
- cp_warning_at (" by `%D'",
- OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
+ cp_warning_at (" by `%D'", fns);
base_fndecls = TREE_CHAIN (base_fndecls);
}
}
implicit_fns = default_fn;
}
- /* Assignment operator. */
- if (! TYPE_HAS_ASSIGN_REF (t) && ! TYPE_FOR_JAVA (t))
- {
- default_fn
- = implicitly_declare_fn (sfk_assignment_operator, t,
- /*const_p=*/!cant_have_const_assignment);
- TREE_CHAIN (default_fn) = implicit_fns;
- implicit_fns = default_fn;
- }
-
+ /* If there is no assignment operator, one will be created if and
+ when it is needed. For now, just record whether or not the type
+ of the parameter to the assignment operator will be a const or
+ non-const reference. */
+ if (!TYPE_HAS_ASSIGN_REF (t) && !TYPE_FOR_JAVA (t))
+ TYPE_HAS_CONST_ASSIGN_REF (t) = !cant_have_const_assignment;
+
/* Now, hook all of the new functions on to TYPE_METHODS,
and add them to the CLASSTYPE_METHOD_VEC. */
for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f))
{
- add_method (t, *f, /*error_p=*/0);
+ add_method (t, *f);
maybe_add_class_template_decl_list (current_class_type, *f, /*friend_p=*/0);
}
if (abi_version_at_least (2))
and a not-in-charge version. */
clone = build_clone (fn, complete_ctor_identifier);
if (update_method_vec_p)
- add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0);
+ add_method (DECL_CONTEXT (clone), clone);
clone = build_clone (fn, base_ctor_identifier);
if (update_method_vec_p)
- add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0);
+ add_method (DECL_CONTEXT (clone), clone);
}
else
{
{
clone = build_clone (fn, deleting_dtor_identifier);
if (update_method_vec_p)
- add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0);
+ add_method (DECL_CONTEXT (clone), clone);
}
clone = build_clone (fn, complete_dtor_identifier);
if (update_method_vec_p)
- add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0);
+ add_method (DECL_CONTEXT (clone), clone);
clone = build_clone (fn, base_dtor_identifier);
if (update_method_vec_p)
- add_method (DECL_CONTEXT (clone), clone, /*error_p=*/0);
+ add_method (DECL_CONTEXT (clone), clone);
}
/* Note that this is an abstract function that is never emitted. */
CLASSTYPE_NON_POD_P (t)
|= (CLASSTYPE_NON_AGGREGATE (t) || TYPE_HAS_DESTRUCTOR (t)
|| TYPE_HAS_ASSIGN_REF (t));
- TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t);
TYPE_HAS_COMPLEX_ASSIGN_REF (t)
|= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t);
build_vtt (t);
if (warn_nonvdtor && TYPE_POLYMORPHIC_P (t) && TYPE_HAS_DESTRUCTOR (t)
- && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1)) == NULL_TREE)
+ && !DECL_VINDEX (CLASSTYPE_DESTRUCTORS (t)))
{
- tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1);
+ tree dtor = CLASSTYPE_DESTRUCTORS (t);
/* Warn only if the dtor is non-private or the class has friends */
if (!TREE_PRIVATE (dtor) ||
unsigned ptrmemfunc_flag : 1;
unsigned was_anonymous : 1;
- unsigned has_real_assign_ref : 1;
unsigned has_const_init_ref : 1;
unsigned has_complex_init_ref : 1;
unsigned has_complex_assign_ref : 1;
- unsigned has_abstract_assign_ref : 1;
unsigned non_aggregate : 1;
unsigned java_interface : 1;
/* There are some bits left to fill out a 32-bit word. Keep track
of this by updating the size of this bitfield whenever you add or
remove a flag. */
- unsigned dummy : 9;
+ unsigned dummy : 11;
tree primary_base;
tree vfields;
tree as_base;
tree pure_virtuals;
tree friend_classes;
- tree GTY ((reorder ("resort_type_method_vec"))) methods;
+ VEC (tree) * GTY((reorder ("resort_type_method_vec"))) methods;
tree key_method;
tree decl_list;
tree template_info;
/* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */
#define TYPE_HAS_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_assign_ref)
+
+/* True iff the class type NODE has an "operator =" whose parameter
+ has a parameter of type "const X&". */
#define TYPE_HAS_CONST_ASSIGN_REF(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->h.has_const_assign_ref)
/* A FUNCTION_DECL or OVERLOAD for the constructors for NODE. These
are the constructors that take an in-charge parameter. */
#define CLASSTYPE_CONSTRUCTORS(NODE) \
- (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), CLASSTYPE_CONSTRUCTOR_SLOT))
+ (VEC_index (tree, CLASSTYPE_METHOD_VEC (NODE), CLASSTYPE_CONSTRUCTOR_SLOT))
/* A FUNCTION_DECL for the destructor for NODE. These are the
destructors that take an in-charge parameter. */
#define CLASSTYPE_DESTRUCTORS(NODE) \
- (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), CLASSTYPE_DESTRUCTOR_SLOT))
+ (VEC_index (tree, CLASSTYPE_METHOD_VEC (NODE), CLASSTYPE_DESTRUCTOR_SLOT))
/* Mark bits for depth-first and breath-first searches. */
(IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE))
/* Nonzero if there is a user-defined X::op=(x&) for this class. */
-#define TYPE_HAS_REAL_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_real_assign_ref)
#define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_assign_ref)
-#define TYPE_HAS_ABSTRACT_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_abstract_assign_ref)
#define TYPE_HAS_COMPLEX_INIT_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_init_ref)
/* Nonzero if TYPE has a trivial destructor. From [class.dtor]:
extern tree get_vtable_decl (tree, int);
extern void resort_type_method_vec
(void *, void *, gt_pointer_operator, void *);
-extern void add_method (tree, tree, int);
+extern void add_method (tree, tree);
extern int currently_open_class (tree);
extern tree currently_open_derived_class (tree);
extern tree finish_struct (tree, tree);
TYPE_HAS_ASSIGN_REF (DECL_CONTEXT (decl)) = 1;
if (assop != 1)
TYPE_HAS_CONST_ASSIGN_REF (DECL_CONTEXT (decl)) = 1;
- if (DECL_PURE_VIRTUAL_P (decl))
- TYPE_HAS_ABSTRACT_ASSIGN_REF (DECL_CONTEXT (decl)) = 1;
}
}
}
if (ix >= 0)
{
- tree methods = CLASSTYPE_METHOD_VEC (ctype);
+ VEC(tree) *methods = CLASSTYPE_METHOD_VEC (ctype);
tree fndecls, fndecl = 0;
bool is_conv_op;
bool pop_p;
const char *format = NULL;
pop_p = push_scope (ctype);
- for (fndecls = TREE_VEC_ELT (methods, ix);
+ for (fndecls = VEC_index (tree, methods, ix);
fndecls; fndecls = OVL_NEXT (fndecls))
{
tree p1, p2;
if (is_conv_op)
ix = CLASSTYPE_FIRST_CONVERSION_SLOT;
- fndecls = TREE_VEC_ELT (methods, ix);
+ fndecls = VEC_index (tree, methods, ix);
while (fndecls)
{
fndecl = OVL_CURRENT (fndecls);
if (!fndecls && is_conv_op)
{
- if (TREE_VEC_LENGTH (methods) > ix)
+ if (VEC_length (tree, methods) > (size_t) ix)
{
ix++;
- fndecls = TREE_VEC_ELT (methods, ix);
+ fndecls = VEC_index (tree, methods, ix);
if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls)))
{
fndecls = NULL_TREE;
case we'll only confuse ourselves when the function is declared
properly within the class. */
if (COMPLETE_TYPE_P (ctype))
- add_method (ctype, function, /*error_p=*/1);
+ add_method (ctype, function);
return NULL_TREE;
}
static tree
locate_dtor (tree type, void *client ATTRIBUTE_UNUSED)
{
- tree fns;
-
- if (!TYPE_HAS_DESTRUCTOR (type))
- return NULL_TREE;
- fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type),
- CLASSTYPE_DESTRUCTOR_SLOT);
- return fns;
+ return CLASSTYPE_DESTRUCTORS (type);
}
/* Locate the default ctor of TYPE. */
if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
return NULL_TREE;
-
- fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type),
- CLASSTYPE_CONSTRUCTOR_SLOT);
- for (; fns; fns = OVL_NEXT (fns))
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
ix = CLASSTYPE_CONSTRUCTOR_SLOT;
if (ix < 0)
return NULL_TREE;
- fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), ix);
+ fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
for (; fns; fns = OVL_NEXT (fns))
{
if (raises)
fn_type = build_exception_variant (fn_type, raises);
fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
+ DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
if (kind == sfk_constructor || kind == sfk_copy_constructor)
DECL_CONSTRUCTOR_P (fn) = 1;
else if (kind == sfk_destructor)
TYPE_UNQUALIFIED);
grok_special_member_properties (fn);
TREE_PUBLIC (fn) = !decl_function_context (TYPE_MAIN_DECL (type));
- cp_finish_decl (fn, /*init=*/NULL_TREE, /*asmspec_tree=*/NULL_TREE,
- /*flags=*/LOOKUP_ONLYCONVERTING);
+ rest_of_decl_compilation (fn, /*asmspec=*/NULL,
+ toplevel_bindings_p (), at_eof);
DECL_IN_AGGR_P (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
DECL_NOT_REALLY_EXTERN (fn) = 1;
{
idx = lookup_fnfields_1 (ctype, name);
if (idx >= 0)
- fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (ctype), idx);
+ fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (ctype), idx);
}
else
{
- tree methods;
+ VEC(tree) *methods;
+ tree ovl;
/* For a type-conversion operator, we cannot do a
name-based lookup. We might be looking for `operator
methods = CLASSTYPE_METHOD_VEC (ctype);
if (methods)
for (idx = CLASSTYPE_FIRST_CONVERSION_SLOT;
- idx < TREE_VEC_LENGTH (methods); ++idx)
+ (ovl = VEC_iterate (tree, methods, idx));
+ ++idx)
{
- tree ovl = TREE_VEC_ELT (methods, idx);
-
- if (!ovl || !DECL_CONV_FN_P (OVL_CURRENT (ovl)))
+ if (!DECL_CONV_FN_P (OVL_CURRENT (ovl)))
/* There are no more conversion functions. */
break;
TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
TYPE_HAS_ASSIGN_REF (type) = TYPE_HAS_ASSIGN_REF (pattern);
TYPE_HAS_CONST_ASSIGN_REF (type) = TYPE_HAS_CONST_ASSIGN_REF (pattern);
- TYPE_HAS_ABSTRACT_ASSIGN_REF (type) = TYPE_HAS_ABSTRACT_ASSIGN_REF (pattern);
TYPE_HAS_INIT_REF (type) = TYPE_HAS_INIT_REF (pattern);
TYPE_HAS_CONST_INIT_REF (type) = TYPE_HAS_CONST_INIT_REF (pattern);
TYPE_HAS_DEFAULT_CONSTRUCTOR (type) = TYPE_HAS_DEFAULT_CONSTRUCTOR (pattern);
fprintf (file, " interface-only");
if (CLASSTYPE_INTERFACE_UNKNOWN (node))
fprintf (file, " interface-unknown");
- print_node (file, "member-functions", CLASSTYPE_METHOD_VEC (node),
- indent + 4);
}
}
pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (bltn_type))
return;
- dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (bltn_type), 1);
+ dtor = CLASSTYPE_DESTRUCTORS (bltn_type);
if (DECL_EXTERNAL (dtor))
return;
doing_runtime = 1;
{
int idx = lookup_fnfields_1 (type, lfi->name);
if (idx >= 0)
- nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
+ nval = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), idx);
}
if (!nval)
{
int pass;
int i;
+ tree fn;
+ VEC(tree) *methods;
- tree methods = CLASSTYPE_METHOD_VEC (class_type);
+ methods = CLASSTYPE_METHOD_VEC (class_type);
for (pass = 0; pass < 2; ++pass)
for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
- i < TREE_VEC_LENGTH (methods);
+ (fn = VEC_iterate (tree, methods, i));
++i)
{
- tree fn = TREE_VEC_ELT (methods, i);
- /* The size of the vector may have some unused slots at the
- end. */
- if (!fn)
- break;
-
/* All the conversion operators come near the beginning of the
class. Therefore, if FN is not a conversion operator, there
is no matching conversion operator in CLASS_TYPE. */
int
lookup_fnfields_1 (tree type, tree name)
{
- tree method_vec;
- tree *methods;
+ VEC(tree) *method_vec;
+ tree fn;
tree tmp;
- int i;
- int len;
-
+ size_t i;
+
if (!CLASS_TYPE_P (type))
return -1;
if (!method_vec)
return -1;
- methods = &TREE_VEC_ELT (method_vec, 0);
- len = TREE_VEC_LENGTH (method_vec);
-
#ifdef GATHER_STATISTICS
n_calls_lookup_fnfields_1++;
#endif /* GATHER_STATISTICS */
/* Constructors are first... */
if (name == ctor_identifier)
- return (methods[CLASSTYPE_CONSTRUCTOR_SLOT]
- ? CLASSTYPE_CONSTRUCTOR_SLOT : -1);
+ {
+ fn = CLASSTYPE_CONSTRUCTORS (type);
+ return fn ? CLASSTYPE_CONSTRUCTOR_SLOT : -1;
+ }
/* and destructors are second. */
if (name == dtor_identifier)
- return (methods[CLASSTYPE_DESTRUCTOR_SLOT]
- ? CLASSTYPE_DESTRUCTOR_SLOT : -1);
+ {
+ fn = CLASSTYPE_DESTRUCTORS (type);
+ return fn ? CLASSTYPE_DESTRUCTOR_SLOT : -1;
+ }
if (IDENTIFIER_TYPENAME_P (name))
return lookup_conversion_operator (type, TREE_TYPE (name));
/* Skip the conversion operators. */
- i = CLASSTYPE_FIRST_CONVERSION_SLOT;
- while (i < len && methods[i] && DECL_CONV_FN_P (OVL_CURRENT (methods[i])))
- i++;
+ for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ (fn = VEC_iterate (tree, method_vec, i));
+ ++i)
+ if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
+ break;
/* If the type is complete, use binary search. */
if (COMPLETE_TYPE_P (type))
{
- int lo = i;
- int hi = len;
+ int lo;
+ int hi;
+
+ /* All non-Java classes have "operator=" -- but we do not
+ actually create the declaration until it is needed. */
+ if (name == ansi_assopname(NOP_EXPR)
+ && !TYPE_HAS_ASSIGN_REF (type)
+ && !TYPE_FOR_JAVA (type))
+ {
+ tree fn;
+
+ /* Declare the function. */
+ fn = implicitly_declare_fn (sfk_assignment_operator, type,
+ TYPE_HAS_CONST_ASSIGN_REF (type));
+ add_method (type, fn);
+ TREE_CHAIN (fn) = TYPE_METHODS (type);
+ TYPE_METHODS (type) = fn;
+ maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
+ method_vec = CLASSTYPE_METHOD_VEC (type);
+ }
+ lo = i;
+ hi = VEC_length (tree, method_vec);
while (lo < hi)
{
i = (lo + hi) / 2;
n_outer_fields_searched++;
#endif /* GATHER_STATISTICS */
- tmp = methods[i];
- /* This slot may be empty; we allocate more slots than we
- need. In that case, the entry we're looking for is
- closer to the beginning of the list. */
- if (tmp)
- tmp = DECL_NAME (OVL_CURRENT (tmp));
- if (!tmp || tmp > name)
+ tmp = VEC_index (tree, method_vec, i);
+ tmp = DECL_NAME (OVL_CURRENT (tmp));
+ if (tmp > name)
hi = i;
else if (tmp < name)
lo = i + 1;
}
}
else
- for (; i < len && methods[i]; ++i)
+ for (;
+ (fn = VEC_iterate (tree, method_vec, i));
+ ++i)
{
#ifdef GATHER_STATISTICS
n_outer_fields_searched++;
#endif /* GATHER_STATISTICS */
-
- tmp = OVL_CURRENT (methods[i]);
- if (DECL_NAME (tmp) == name)
+ if (DECL_NAME (OVL_CURRENT (fn)) == name)
return i;
}
ix = lookup_fnfields_1 (type, DECL_NAME (fndecl));
if (ix >= 0)
{
- tree fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), ix);
+ tree fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
for (; fns; fns = OVL_NEXT (fns))
{
static tree
add_conversions (tree binfo, void *data)
{
- int i;
- tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
+ size_t i;
+ VEC(tree) *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
tree *conversions = (tree *) data;
+ tree tmp;
/* Some builtin types have no method vector, not even an empty one. */
if (!method_vec)
return NULL_TREE;
- for (i = 2; i < TREE_VEC_LENGTH (method_vec); ++i)
+ for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ (tmp = VEC_iterate (tree, method_vec, i));
+ ++i)
{
- tree tmp = TREE_VEC_ELT (method_vec, i);
tree name;
if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp)))
{
/* We also need to add this function to the
CLASSTYPE_METHOD_VEC. */
- add_method (current_class_type, decl, /*error_p=*/0);
+ add_method (current_class_type, decl);
TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
TYPE_METHODS (current_class_type) = decl;
removed object. This is an O(1) operation. */
#define VEC_unordered_remove(TDEF,V,I) (VEC_OP(TDEF,unordered_remove)(V,I))
+/* Get the address of the array of elements
+ T *VEC_T_address (VEC(T) v)
+
+ If you need to directly manipulate the array (for instance, you
+ want to feed it to qsort), use this accessor. */
+#define VEC_address(TDEF,V) (VEC_OP(TDEF,address)(V))
+
#if !IN_GENGTYPE
/* Reallocate an array of elements with prefix. */
extern void *vec_p_reserve (void *, int MEM_STAT_DECL);
return obj_; \
} \
\
+static inline TDEF *VEC_OP (TDEF,address) \
+ (VEC (TDEF) *vec_) \
+{ \
+ return vec_ ? vec_->vec : 0; \
+} \
+ \
struct vec_swallow_trailing_semi
#endif
vec_->vec[ix_] = vec_->vec[--vec_->num]; \
} \
\
+static inline TDEF *VEC_OP (TDEF,address) \
+ (VEC (TDEF) *vec_) \
+{ \
+ return vec_ ? vec_->vec : 0; \
+} \
+ \
struct vec_swallow_trailing_semi
#endif