Commit b991151b by Nathan Sidwell Committed by Nathan Sidwell

name-lookup.h (lookup_field_1): Delete.

	* name-lookup.h (lookup_field_1): Delete.
	(get_class_binding_direct, get_class_binding): Add type_or_fns arg.
	* name-lookup.c	(lookup_field_1): make static
	(method_vec_binary_search, method_vec_linear_search): New.  Broken
	out of ...
	(get_class_binding_direct): ... here.  Add TYPE_OR_FNS argument.
	Do complete search of this level.
	(get_class_binding): Adjust.
	* decl.c (reshape_init_class): Call get_class_binding.
	* search.c (lookup_field_r): Move field searching into
	get_class_binding_direct.

From-SVN: r251808
parent ec7f007c
2017-09-06 Nathan Sidwell <nathan@acm.org>
* name-lookup.h (lookup_field_1): Delete.
(get_class_binding_direct, get_class_binding): Add type_or_fns arg.
* name-lookup.c (lookup_field_1): make static
(method_vec_binary_search, method_vec_linear_search): New. Broken
out of ...
(get_class_binding_direct): ... here. Add TYPE_OR_FNS argument.
Do complete search of this level.
(get_class_binding): Adjust.
* decl.c (reshape_init_class): Call get_class_binding.
* search.c (lookup_field_r): Move field searching into
get_class_binding_direct.
* class.c (warn_hidden): Don't barf on non-functions.
* decl2.c (check_classfn): Likewise. Check template match earlier.
......
......@@ -5746,7 +5746,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
/* We already reshaped this. */
gcc_assert (d->cur->index == field);
else if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE)
field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);
field = get_class_binding (type, d->cur->index, false);
else
{
if (complain & tf_error)
......
......@@ -1113,79 +1113,54 @@ extract_conversion_operator (tree fns, tree type)
return convs;
}
/* TYPE is a class type. Return the member functions in the method
vector with name NAME. Does not lazily declare implicitly-declared
member functions. */
/* Binary search of (ordered) METHOD_VEC for NAME. */
tree
get_class_binding_direct (tree type, tree name)
static tree
method_vec_binary_search (vec<tree, va_gc> *method_vec, tree name)
{
vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (type);
if (!method_vec)
return NULL_TREE;
/* Conversion operators can only be found by the marker conversion
operator name. */
bool conv_op = IDENTIFIER_CONV_OP_P (name);
tree lookup = conv_op ? conv_op_identifier : name;
tree val = NULL_TREE;
tree fns;
/* If the type is complete, use binary search. */
if (COMPLETE_TYPE_P (type))
for (unsigned lo = 0, hi = method_vec->length (); lo < hi;)
{
int lo = 0;
int hi = method_vec->length ();
while (lo < hi)
{
int i = (lo + hi) / 2;
unsigned mid = (lo + hi) / 2;
tree binding = (*method_vec)[mid];
tree binding_name = OVL_NAME (binding);
fns = (*method_vec)[i];
tree fn_name = OVL_NAME (fns);
if (fn_name > lookup)
hi = i;
else if (fn_name < lookup)
lo = i + 1;
else
{
val = fns;
break;
}
}
}
if (binding_name > name)
hi = mid;
else if (binding_name < name)
lo = mid + 1;
else
for (int i = 0; vec_safe_iterate (method_vec, i, &fns); ++i)
/* We can get a NULL binding during insertion of a new
method name, because the identifier_binding machinery
performs a lookup. If we find such a NULL slot, that's
the thing we were looking for, so we might as well bail
out immediately. */
if (!fns)
break;
else if (OVL_NAME (fns) == lookup)
{
val = fns;
break;
return binding;
}
/* Extract the conversion operators asked for, unless the general
conversion operator was requested. */
if (val && conv_op)
return NULL_TREE;
}
/* Linear search of (unordered) METHOD_VEC for NAME. */
static tree
method_vec_linear_search (vec<tree, va_gc> *method_vec, tree name)
{
for (int ix = method_vec->length (); ix--;)
/* We can get a NULL binding during insertion of a new method
name, because the identifier_binding machinery performs a
lookup. If we find such a NULL slot, that's the thing we were
looking for, so we might as well bail out immediately. */
if (tree binding = (*method_vec)[ix])
{
gcc_checking_assert (OVL_FUNCTION (val) == conv_op_marker);
val = OVL_CHAIN (val);
if (tree type = TREE_TYPE (name))
val = extract_conversion_operator (val, type);
if (OVL_NAME (binding) == name)
return binding;
}
else
break;
return val;
return NULL_TREE;
}
/* Do a 1-level search for NAME as a member of TYPE. The caller must
figure out whether it can access this field. (Since it is only one
level, this is reasonable.) */
tree
static tree
lookup_field_1 (tree type, tree name, bool want_type)
{
tree field;
......@@ -1281,11 +1256,62 @@ lookup_field_1 (tree type, tree name, bool want_type)
return NULL_TREE;
}
/* TYPE is a class type. Return the overloads in
the method vector with name NAME. Lazily create ctors etc. */
/* Look for NAME as an immediate member of KLASS (including
anon-members or unscoped enum member). TYPE_OR_FNS is zero for
regular search. >0 to get a type binding (if there is one) and <0
if you want (just) the member function binding.
Use this if you do not want lazy member creation. */
tree
get_class_binding_direct (tree klass, tree name, int type_or_fns)
{
gcc_checking_assert (RECORD_OR_UNION_TYPE_P (klass));
/* Conversion operators can only be found by the marker conversion
operator name. */
bool conv_op = IDENTIFIER_CONV_OP_P (name);
tree lookup = conv_op ? conv_op_identifier : name;
tree val = NULL_TREE;
if (type_or_fns > 0)
/* User wants type. Don't look in method_vec. */;
else if (vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (klass))
{
if (COMPLETE_TYPE_P (klass))
val = method_vec_binary_search (method_vec, lookup);
else
val = method_vec_linear_search (method_vec, lookup);
}
if (type_or_fns < 0)
/* User wants functions. Don't look for a field. */;
else if (!val || (TREE_CODE (val) == OVERLOAD && OVL_USING_P (val)))
/* Dependent using declarations are a 'field', make sure we
return that even if we saw an overload already. */
if (tree field_val = lookup_field_1 (klass, lookup, type_or_fns > 0))
if (!val || TREE_CODE (field_val) == USING_DECL)
val = field_val;
/* Extract the conversion operators asked for, unless the general
conversion operator was requested. */
if (val && conv_op)
{
gcc_checking_assert (OVL_FUNCTION (val) == conv_op_marker);
val = OVL_CHAIN (val);
if (tree type = TREE_TYPE (name))
val = extract_conversion_operator (val, type);
}
return val;
}
/* Look for NAME's binding in exactly KLASS. See
get_class_binding_direct for argument description. Does lazy
special function creation as necessary. */
tree
get_class_binding (tree type, tree name)
get_class_binding (tree type, tree name, int type_or_fns)
{
type = complete_type (type);
......@@ -1314,7 +1340,7 @@ get_class_binding (tree type, tree name)
}
}
return get_class_binding_direct (type, name);
return get_class_binding_direct (type, name, type_or_fns);
}
/* Find the slot containing overloads called 'NAME'. If there is no
......
......@@ -319,9 +319,8 @@ extern void pop_decl_namespace (void);
extern void do_namespace_alias (tree, tree);
extern tree do_class_using_decl (tree, tree);
extern tree lookup_arg_dependent (tree, tree, vec<tree, va_gc> *);
extern tree lookup_field_1 (tree, tree, bool);
extern tree get_class_binding_direct (tree, tree);
extern tree get_class_binding (tree, tree);
extern tree get_class_binding_direct (tree, tree, int type_or_fns = -1);
extern tree get_class_binding (tree, tree, int type_or_fns = -1);
extern tree *get_method_slot (tree klass, tree name);
extern void resort_type_method_vec (void *, void *,
gt_pointer_operator, void *);
......
......@@ -974,23 +974,7 @@ lookup_field_r (tree binfo, void *data)
&& !BINFO_VIRTUAL_P (binfo))
return dfs_skip_bases;
/* First, look for a function. There can't be a function and a data
member with the same name, and if there's a function and a type
with the same name, the type is hidden by the function. */
if (!lfi->want_type)
nval = get_class_binding (type, lfi->name);
if (!nval)
/* Look for a data member or type. */
nval = lookup_field_1 (type, lfi->name, lfi->want_type);
else if (TREE_CODE (nval) == OVERLOAD && OVL_USING_P (nval))
{
/* If we have both dependent and non-dependent using-declarations, return
the dependent one rather than an incomplete list of functions. */
tree dep_using = lookup_field_1 (type, lfi->name, lfi->want_type);
if (dep_using && TREE_CODE (dep_using) == USING_DECL)
nval = dep_using;
}
nval = get_class_binding (type, lfi->name, lfi->want_type);
/* If we're looking up a type (as with an elaborated type specifier)
we ignore all non-types we find. */
......
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