bool
add_method (tree type, tree method, bool via_using)
{
- unsigned slot;
- bool template_conv_p = false;
- bool conv_p;
- vec<tree, va_gc> *method_vec;
- bool complete_p;
- bool insert_p = false;
- tree current_fns;
-
if (method == error_mark_node)
return false;
- complete_p = COMPLETE_TYPE_P (type);
- conv_p = DECL_CONV_FN_P (method);
- if (conv_p)
- template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
- && DECL_TEMPLATE_CONV_FN_P (method));
+ bool complete_p = COMPLETE_TYPE_P (type);
+ bool conv_p = DECL_CONV_FN_P (method);
- method_vec = CLASSTYPE_METHOD_VEC (type);
+ vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (type);
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. */
+ /* Make a new method vector. We start with 8 entries. */
vec_alloc (method_vec, 8);
CLASSTYPE_METHOD_VEC (type) = method_vec;
}
/* Maintain TYPE_HAS_USER_CONSTRUCTOR, etc. */
grok_special_member_properties (method);
+ bool insert_p = true;
+ unsigned slot;
tree m;
- insert_p = true;
/* See if we already have an entry with this name. */
for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
vec_safe_iterate (method_vec, slot, &m);
++slot)
{
m = OVL_FIRST (m);
- if (template_conv_p)
+ if (conv_p)
{
- if (TREE_CODE (m) == TEMPLATE_DECL
- && DECL_TEMPLATE_CONV_FN_P (m))
+ if (DECL_CONV_FN_P (m))
insert_p = false;
break;
}
- if (conv_p && !DECL_CONV_FN_P (m))
- break;
if (DECL_NAME (m) == DECL_NAME (method))
{
insert_p = false;
&& DECL_NAME (m) > DECL_NAME (method))
break;
}
- current_fns = insert_p ? NULL_TREE : (*method_vec)[slot];
+ tree current_fns = insert_p ? NULL_TREE : (*method_vec)[slot];
+ gcc_assert (!DECL_EXTERN_C_P (method));
/* Check to see if we've already got this method. */
for (ovl_iterator iter (current_fns); iter; ++iter)
}
/* A class should never have more than one destructor. */
- if (current_fns && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
- return false;
+ gcc_assert (!current_fns || !DECL_DESTRUCTOR_P (method));
current_fns = ovl_insert (method, current_fns, via_using);
static tree dfs_debug_mark (tree, void *);
static int check_hidden_convs (tree, int, int, tree, tree, tree);
static tree split_conversions (tree, tree, tree, tree);
-static int lookup_conversions_r (tree, int, int,
- tree, tree, tree, tree, tree *, tree *);
+static int lookup_conversions_r (tree, int, int, tree, tree, tree *);
static int look_for_overrides_r (tree, tree);
static tree lookup_field_r (tree, void *);
static tree dfs_accessible_post (tree, void *);
}
/* Worker for lookup_conversions. Lookup conversion functions in
- BINFO and its children. VIRTUAL_DEPTH is nonzero, if BINFO is in
- a morally virtual base, and VIRTUALNESS is nonzero, if we've
- encountered virtual bases already in the tree walk. PARENT_CONVS &
- PARENT_TPL_CONVS are lists of list of conversions within parent
- binfos. OTHER_CONVS and OTHER_TPL_CONVS are conversions found
- elsewhere in the tree. Return the conversions found within this
- portion of the graph in CONVS and TPL_CONVS. Return nonzero is we
- encountered virtualness. We keep template and non-template
+ BINFO and its children. VIRTUAL_DEPTH is nonzero, if BINFO is in a
+ morally virtual base, and VIRTUALNESS is nonzero, if we've
+ encountered virtual bases already in the tree walk. PARENT_CONVS
+ is a list of conversions within parent binfos. OTHER_CONVS are
+ conversions found elsewhere in the tree. Return the conversions
+ found within this portion of the graph in CONVS. Return nonzero if
+ we encountered virtualness. We keep template and non-template
conversions separate, to avoid unnecessary type comparisons.
The located conversion functions are held in lists of lists. The
is the converted-to type. */
static int
-lookup_conversions_r (tree binfo,
- int virtual_depth, int virtualness,
- tree parent_convs, tree parent_tpl_convs,
- tree other_convs, tree other_tpl_convs,
- tree *convs, tree *tpl_convs)
+lookup_conversions_r (tree binfo, int virtual_depth, int virtualness,
+ tree parent_convs, tree other_convs, tree *convs)
{
int my_virtualness = 0;
tree my_convs = NULL_TREE;
- tree my_tpl_convs = NULL_TREE;
tree child_convs = NULL_TREE;
- tree child_tpl_convs = NULL_TREE;
- unsigned i;
- tree base_binfo;
- vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
- tree conv;
/* If we have no conversion operators, then don't look. */
if (!TYPE_HAS_CONVERSION (BINFO_TYPE (binfo)))
{
- *convs = *tpl_convs = NULL_TREE;
+ *convs = NULL_TREE;
return 0;
}
virtual_depth++;
/* First, locate the unhidden ones at this level. */
- for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
- vec_safe_iterate (method_vec, i, &conv);
- ++i)
- {
- tree cur = OVL_FIRST (conv);
-
- if (!DECL_CONV_FN_P (cur))
- break;
+ vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
+ tree conv = NULL_TREE;
+ vec_safe_iterate (method_vec, CLASSTYPE_FIRST_CONVERSION_SLOT, &conv);
+ if (conv && !DECL_CONV_FN_P (OVL_FIRST (conv)))
+ conv = NULL_TREE;
- if (TREE_CODE (cur) == TEMPLATE_DECL)
- /* Only template conversions can be overloaded, and we must
- flatten them out and check each one individually. */
- for (ovl_iterator iter (conv); iter; ++iter)
- {
- tree tpl = *iter;
- tree type = DECL_CONV_FN_TYPE (tpl);
+ for (ovl_iterator iter (conv); iter; ++iter)
+ {
+ tree fn = *iter;
+ tree type = DECL_CONV_FN_TYPE (fn);
- if (check_hidden_convs (binfo, virtual_depth, virtualness,
- type, parent_tpl_convs, other_tpl_convs))
- {
- my_tpl_convs = tree_cons (binfo, tpl, my_tpl_convs);
- TREE_TYPE (my_tpl_convs) = type;
- if (virtual_depth)
- {
- TREE_STATIC (my_tpl_convs) = 1;
- my_virtualness = 1;
- }
- }
- }
- else
+ if (TREE_CODE (fn) != TEMPLATE_DECL && type_uses_auto (type))
{
- tree name = DECL_NAME (cur);
+ mark_used (fn);
+ type = DECL_CONV_FN_TYPE (fn);
+ }
- if (!IDENTIFIER_MARKED (name))
+ if (check_hidden_convs (binfo, virtual_depth, virtualness,
+ type, parent_convs, other_convs))
+ {
+ my_convs = tree_cons (binfo, fn, my_convs);
+ TREE_TYPE (my_convs) = type;
+ if (virtual_depth)
{
- tree type = DECL_CONV_FN_TYPE (cur);
- if (type_uses_auto (type))
- {
- mark_used (cur);
- type = DECL_CONV_FN_TYPE (cur);
- }
-
- if (check_hidden_convs (binfo, virtual_depth, virtualness,
- type, parent_convs, other_convs))
- {
- my_convs = tree_cons (binfo, conv, my_convs);
- TREE_TYPE (my_convs) = type;
- if (virtual_depth)
- {
- TREE_STATIC (my_convs) = 1;
- my_virtualness = 1;
- }
- IDENTIFIER_MARKED (name) = 1;
- }
+ TREE_STATIC (my_convs) = 1;
+ my_virtualness = 1;
}
}
}
TREE_STATIC (parent_convs) = 1;
}
- if (my_tpl_convs)
- {
- parent_tpl_convs = tree_cons (binfo, my_tpl_convs, parent_tpl_convs);
- if (virtual_depth)
- TREE_STATIC (parent_tpl_convs) = 1;
- }
-
child_convs = other_convs;
- child_tpl_convs = other_tpl_convs;
/* Now iterate over each base, looking for more conversions. */
+ unsigned i;
+ tree base_binfo;
for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
{
- tree base_convs, base_tpl_convs;
+ tree base_convs;
unsigned base_virtualness;
base_virtualness = lookup_conversions_r (base_binfo,
virtual_depth, virtualness,
- parent_convs, parent_tpl_convs,
- child_convs, child_tpl_convs,
- &base_convs, &base_tpl_convs);
+ parent_convs, child_convs,
+ &base_convs);
if (base_virtualness)
my_virtualness = virtualness = 1;
child_convs = chainon (base_convs, child_convs);
- child_tpl_convs = chainon (base_tpl_convs, child_tpl_convs);
}
- /* Unmark the conversions found at this level */
- for (conv = my_convs; conv; conv = TREE_CHAIN (conv))
- IDENTIFIER_MARKED (OVL_NAME (TREE_VALUE (conv))) = 0;
-
*convs = split_conversions (my_convs, parent_convs,
child_convs, other_convs);
- *tpl_convs = split_conversions (my_tpl_convs, parent_tpl_convs,
- child_tpl_convs, other_tpl_convs);
return my_virtualness;
}
tree
lookup_conversions (tree type)
{
- tree convs, tpl_convs;
- tree list = NULL_TREE;
+ tree convs;
complete_type (type);
if (!CLASS_TYPE_P (type) || !TYPE_BINFO (type))
return NULL_TREE;
- lookup_conversions_r (TYPE_BINFO (type), 0, 0,
- NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
- &convs, &tpl_convs);
+ lookup_conversions_r (TYPE_BINFO (type), 0, 0, NULL_TREE, NULL_TREE, &convs);
+ tree list = NULL_TREE;
+
/* Flatten the list-of-lists */
for (; convs; convs = TREE_CHAIN (convs))
{
}
}
- for (; tpl_convs; tpl_convs = TREE_CHAIN (tpl_convs))
- {
- tree probe, next;
-
- for (probe = TREE_VALUE (tpl_convs); probe; probe = next)
- {
- next = TREE_CHAIN (probe);
-
- TREE_CHAIN (probe) = list;
- list = probe;
- }
- }
-
return list;
}