From: Nathan Sidwell Date: Wed, 6 Sep 2017 15:32:46 +0000 (+0000) Subject: name-lookup.h (lookup_field_1): Delete. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b991151b284774c5fba4fc3148728c41a21c5004;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a48237235ba..c1546308f7c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,17 @@ 2017-09-06 Nathan Sidwell + * 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. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 655445b9c8e..6f3a348f9fd 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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) diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index ccfb630e4dd..7549edd1dba 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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 *method_vec, tree name) { - vec *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 + return binding; } - 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; - } - /* 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 NULL_TREE; +} - return val; +/* Linear search of (unordered) METHOD_VEC for NAME. */ + +static tree +method_vec_linear_search (vec *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]) + { + if (OVL_NAME (binding) == name) + return binding; + } + else + break; + + 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 *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 diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 0051bfcced9..3bc06d7da98 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -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 *); -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 *); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 38be467b7c6..11e721fc056 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -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. */