aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-08-24 18:39:41 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-08-24 18:39:41 +0000
commit2e12a8554c9ed35fd6aa786c1ef5eee96bf8a6b6 (patch)
tree8339ac9ae0c5848cd0dda14a0ea1525cbbb1cc91
parent281de9c2d56a910fd4321785f9a8c97fc647b8a5 (diff)
downloadgcc-2e12a8554c9ed35fd6aa786c1ef5eee96bf8a6b6.zip
gcc-2e12a8554c9ed35fd6aa786c1ef5eee96bf8a6b6.tar.gz
gcc-2e12a8554c9ed35fd6aa786c1ef5eee96bf8a6b6.tar.bz2
Conversion operators kept on single overload set
Conversion operators kept on single overload set * class.c (add_method): Keep all conv-ops on one slot. * name-lookup.c (lookup_conversion_operator): Pull the desired conv op out of overload set. * search.c (lookup_conversions_r): Lose template/non-template distinction. (lookup_conversions): Likewise. From-SVN: r251340
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/class.c38
-rw-r--r--gcc/cp/name-lookup.c33
-rw-r--r--gcc/cp/search.c149
4 files changed, 77 insertions, 153 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5d2a3c6..92ecf91 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2017-08-24 Nathan Sidwell <nathan@acm.org>
+
+ Conversion operators kept on single overload set
+ * class.c (add_method): Keep all conv-ops on one slot.
+ * name-lookup.c (lookup_conversion_operator): Pull the desired
+ conv op out of overload set.
+ * search.c (lookup_conversions_r): Lose template/non-template
+ distinction.
+ (lookup_conversions): Likewise.
+
2017-08-23 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (lookup_field_1, lookup_fnfields_slot,
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 78a9b5f..a08ce89 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1014,30 +1014,16 @@ modify_vtable_entry (tree t,
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;
}
@@ -1045,24 +1031,22 @@ add_method (tree type, tree method, bool via_using)
/* 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;
@@ -1073,7 +1057,8 @@ add_method (tree type, tree method, bool via_using)
&& 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)
@@ -1216,8 +1201,7 @@ add_method (tree type, tree method, bool via_using)
}
/* 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);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 12c507e..3d69e1d 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -1096,34 +1096,31 @@ lookup_arg_dependent (tree name, tree fns, vec<tree, va_gc> *args)
static tree
lookup_conversion_operator (tree class_type, tree type)
{
- tree tpls = NULL_TREE;
+ tree convs = NULL_TREE;
if (TYPE_HAS_CONVERSION (class_type))
{
- tree fns;
+ tree fns = NULL_TREE;
+ tree tpls = NULL_TREE;
vec<tree, va_gc> *methods = CLASSTYPE_METHOD_VEC (class_type);
- for (int i = CLASSTYPE_FIRST_CONVERSION_SLOT;
- vec_safe_iterate (methods, i, &fns); ++i)
+ vec_safe_iterate (methods, CLASSTYPE_FIRST_CONVERSION_SLOT, &fns);
+ if (fns && !DECL_CONV_FN_P (OVL_FIRST (fns)))
+ fns = NULL_TREE;
+ for (ovl_iterator iter (fns); iter; ++iter)
{
- /* 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. */
- tree fn = OVL_FIRST (fns);
- if (!DECL_CONV_FN_P (fn))
- break;
+ if (same_type_p (DECL_CONV_FN_TYPE (*iter), type))
+ convs = lookup_add (*iter, convs);
- if (TREE_CODE (fn) == TEMPLATE_DECL)
- /* All the templated conversion functions are on the same
- slot, so remember it. */
- tpls = fns;
- else if (same_type_p (DECL_CONV_FN_TYPE (fn), type))
- return fns;
+ if (TREE_CODE (*iter) == TEMPLATE_DECL)
+ tpls = lookup_add (*iter, tpls);
}
+
+ if (!convs)
+ convs = tpls;
}
- return tpls;
+ return convs;
}
/* TYPE is a class type. Return the member functions in the method
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 9e15b02..31f4dd6 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -38,8 +38,7 @@ static tree dfs_dcast_hint_post (tree, void *);
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 *);
@@ -2333,14 +2332,13 @@ split_conversions (tree my_convs, tree parent_convs,
}
/* 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
@@ -2353,26 +2351,17 @@ split_conversions (tree my_convs, tree parent_convs,
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;
}
@@ -2381,60 +2370,32 @@ lookup_conversions_r (tree binfo,
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;
}
}
}
@@ -2446,41 +2407,27 @@ lookup_conversions_r (tree binfo,
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;
}
@@ -2497,17 +2444,16 @@ lookup_conversions_r (tree binfo,
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))
{
@@ -2522,19 +2468,6 @@ lookup_conversions (tree type)
}
}
- 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;
}