From 9e931c2a2819523ce7847b622eaf8ae5f740744e Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 23 Aug 2017 21:09:03 +0000 Subject: [PATCH] cp-tree.h (lookup_field_1, [...]): Move declatations to ... * cp-tree.h (lookup_field_1, lookup_fnfields_slot, lookup_fnfields_slot_nolazy, lookup_all_conversions): Move declatations to ... * name-lookup.h (lookup_field_1, lookup_fnfields_slot, lookup_fnfields_slot_nolazy, lookup_all_conversions): ... here. * search.c (lookup_conversion_operator, lookup_fnfields_slot_nolazy, lookup_field_1, lookup_fnfields_slot, lookup_all_conversions): Move to ... * name-lookup.c (lookup_conversion_operator, lookup_fnfields_slot_nolazy, lookup_field_1, lookup_fnfields_slot, lookup_all_conversions): ... here. From-SVN: r251319 --- gcc/cp/ChangeLog | 12 ++ gcc/cp/cp-tree.h | 4 - gcc/cp/name-lookup.c | 254 ++++++++++++++++++++++++++++++++++++++++++- gcc/cp/name-lookup.h | 4 + gcc/cp/search.c | 252 ------------------------------------------ 5 files changed, 269 insertions(+), 257 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 94c55eded4d..5d2a3c6ebf6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,17 @@ 2017-08-23 Nathan Sidwell + * cp-tree.h (lookup_field_1, lookup_fnfields_slot, + lookup_fnfields_slot_nolazy, lookup_all_conversions): Move + declatations to ... + * name-lookup.h (lookup_field_1, lookup_fnfields_slot, + lookup_fnfields_slot_nolazy, lookup_all_conversions): ... here. + * search.c (lookup_conversion_operator, + lookup_fnfields_slot_nolazy, lookup_field_1, lookup_fnfields_slot, + lookup_all_conversions): Move to ... + * name-lookup.c (lookup_conversion_operator, + lookup_fnfields_slot_nolazy, lookup_field_1, lookup_fnfields_slot, + lookup_all_conversions): ... here. + * semantics.c (finish_member_declaration): Move USING_DECL check earlier. Always set C++ linkage. Commonize TYPE_FIELD and template decl list insertion. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d80cd298535..b915bd9603f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6563,11 +6563,7 @@ extern tree lookup_base (tree, tree, base_access, extern tree dcast_base_hint (tree, tree); extern int accessible_p (tree, tree, bool); extern int accessible_in_template_p (tree, tree); -extern tree lookup_field_1 (tree, tree, bool); extern tree lookup_field (tree, tree, int, bool); -extern tree lookup_fnfields_slot (tree, tree); -extern tree lookup_fnfields_slot_nolazy (tree, tree); -extern tree lookup_all_conversions (tree); extern tree lookup_fnfields (tree, tree, int); extern tree lookup_member (tree, tree, int, bool, tsubst_flags_t, diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 0aad17885c7..12c507ec124 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1089,6 +1089,258 @@ lookup_arg_dependent (tree name, tree fns, vec *args) return fns; } +/* Return the conversion operators in CLASS_TYPE corresponding to + "operator TYPE ()". Only CLASS_TYPE itself is searched; this + routine does not scan the base classes of CLASS_TYPE. */ + +static tree +lookup_conversion_operator (tree class_type, tree type) +{ + tree tpls = NULL_TREE; + + if (TYPE_HAS_CONVERSION (class_type)) + { + tree fns; + vec *methods = CLASSTYPE_METHOD_VEC (class_type); + + for (int i = CLASSTYPE_FIRST_CONVERSION_SLOT; + vec_safe_iterate (methods, i, &fns); ++i) + { + /* 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 (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; + } + } + + return tpls; +} + +/* TYPE is a class type. Return the member functions in the method + vector with name NAME. Does not lazily declare implicitly-declared + member functions. */ + +tree +lookup_fnfields_slot_nolazy (tree type, tree name) +{ + vec *method_vec = CLASSTYPE_METHOD_VEC (type); + if (!method_vec) + return NULL_TREE; + + if (IDENTIFIER_CONV_OP_P (name)) + return lookup_conversion_operator (type, TREE_TYPE (name)); + + /* Skip the conversion operators. */ + int i; + tree fns; + for (i = CLASSTYPE_FIRST_CONVERSION_SLOT; + vec_safe_iterate (method_vec, i, &fns); + ++i) + if (!DECL_CONV_FN_P (OVL_FIRST (fns))) + break; + + /* If the type is complete, use binary search. */ + if (COMPLETE_TYPE_P (type)) + { + int lo; + int hi; + + lo = i; + hi = method_vec->length (); + while (lo < hi) + { + i = (lo + hi) / 2; + + fns = (*method_vec)[i]; + tree fn_name = OVL_NAME (fns); + if (fn_name > name) + hi = i; + else if (fn_name < name) + lo = i + 1; + else + return fns; + } + } + else + for (; vec_safe_iterate (method_vec, i, &fns); ++i) + { + if (OVL_NAME (fns) == name) + return fns; + } + + 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 +lookup_field_1 (tree type, tree name, bool want_type) +{ + tree field; + + gcc_assert (identifier_p (name) && RECORD_OR_UNION_TYPE_P (type)); + + if (CLASSTYPE_SORTED_FIELDS (type)) + { + tree *fields = &CLASSTYPE_SORTED_FIELDS (type)->elts[0]; + int lo = 0, hi = CLASSTYPE_SORTED_FIELDS (type)->len; + int i; + + while (lo < hi) + { + i = (lo + hi) / 2; + + if (DECL_NAME (fields[i]) > name) + hi = i; + else if (DECL_NAME (fields[i]) < name) + lo = i + 1; + else + { + field = NULL_TREE; + + /* We might have a nested class and a field with the + same name; we sorted them appropriately via + field_decl_cmp, so just look for the first or last + field with this name. */ + if (want_type) + { + do + field = fields[i--]; + while (i >= lo && DECL_NAME (fields[i]) == name); + if (!DECL_DECLARES_TYPE_P (field)) + field = NULL_TREE; + } + else + { + do + field = fields[i++]; + while (i < hi && DECL_NAME (fields[i]) == name); + } + + if (field) + { + field = strip_using_decl (field); + if (is_overloaded_fn (field)) + field = NULL_TREE; + } + + return field; + } + } + return NULL_TREE; + } + + field = TYPE_FIELDS (type); + + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) + { + tree decl = field; + + if (DECL_DECLARES_FUNCTION_P (decl)) + /* Functions are kep separately, at the moment. */ + continue; + + gcc_assert (DECL_P (field)); + if (DECL_NAME (field) == NULL_TREE + && ANON_AGGR_TYPE_P (TREE_TYPE (field))) + { + tree temp = lookup_field_1 (TREE_TYPE (field), name, want_type); + if (temp) + return temp; + } + + if (TREE_CODE (decl) == USING_DECL + && DECL_NAME (decl) == name) + { + decl = strip_using_decl (decl); + if (is_overloaded_fn (decl)) + continue; + } + + if (DECL_NAME (decl) == name + && (!want_type || DECL_DECLARES_TYPE_P (decl))) + return decl; + } + + /* We used to special-case vptr_identifier. Make sure it's not + special any more. */ + gcc_assert (name != vptr_identifier || !TYPE_VFIELD (type)); + + return NULL_TREE; +} + +/* TYPE is a class type. Return the overloads in + the method vector with name NAME. Lazily create ctors etc. */ + +tree +lookup_fnfields_slot (tree type, tree name) +{ + type = complete_type (type); + + if (COMPLETE_TYPE_P (type)) + { + if (IDENTIFIER_CTOR_P (name)) + { + if (CLASSTYPE_LAZY_DEFAULT_CTOR (type)) + lazily_declare_fn (sfk_constructor, type); + if (CLASSTYPE_LAZY_COPY_CTOR (type)) + lazily_declare_fn (sfk_copy_constructor, type); + if (CLASSTYPE_LAZY_MOVE_CTOR (type)) + lazily_declare_fn (sfk_move_constructor, type); + } + else if (name == cp_assignment_operator_id (NOP_EXPR)) + { + if (CLASSTYPE_LAZY_COPY_ASSIGN (type)) + lazily_declare_fn (sfk_copy_assignment, type); + if (CLASSTYPE_LAZY_MOVE_ASSIGN (type)) + lazily_declare_fn (sfk_move_assignment, type); + } + else if (IDENTIFIER_DTOR_P (name)) + { + if (CLASSTYPE_LAZY_DESTRUCTOR (type)) + lazily_declare_fn (sfk_destructor, type); + } + } + + return lookup_fnfields_slot_nolazy (type, name); +} + +/* Collect all the conversion operators of KLASS. */ + +tree +lookup_all_conversions (tree klass) +{ + tree lkp = NULL_TREE; + + if (vec *methods = CLASSTYPE_METHOD_VEC (klass)) + { + tree ovl; + for (int idx = CLASSTYPE_FIRST_CONVERSION_SLOT; + methods->iterate (idx, &ovl); ++idx) + { + if (!DECL_CONV_FN_P (OVL_FIRST (ovl))) + /* There are no more conversion functions. */ + break; + + lkp = lookup_add (ovl, lkp); + } + } + + return lkp; +} + /* Compute the chain index of a binding_entry given the HASH value of its name and the total COUNT of chains. COUNT is assumed to be a power of 2. */ @@ -3319,7 +3571,7 @@ do_pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend) current_function_decl = function_decl; return x; } - + /* Inject X into the local scope just before the function parms. */ tree diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 2e2075c630d..1f671479fec 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -319,6 +319,10 @@ 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 lookup_fnfields_slot (tree, tree); +extern tree lookup_fnfields_slot_nolazy (tree, tree); +extern tree lookup_all_conversions (tree); extern tree innermost_non_namespace_value (tree); extern cxx_binding *outer_binding (tree, cxx_binding *, bool); extern void cp_emit_debug_info_for_using (tree, tree); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index bb2219fb040..9e15b02cae6 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -353,106 +353,6 @@ dcast_base_hint (tree subtype, tree target) Otherwise, return a DECL with the indicated name. If WANT_TYPE is true, type declarations are preferred. */ -/* 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 -lookup_field_1 (tree type, tree name, bool want_type) -{ - tree field; - - gcc_assert (identifier_p (name) && RECORD_OR_UNION_TYPE_P (type)); - - if (CLASSTYPE_SORTED_FIELDS (type)) - { - tree *fields = &CLASSTYPE_SORTED_FIELDS (type)->elts[0]; - int lo = 0, hi = CLASSTYPE_SORTED_FIELDS (type)->len; - int i; - - while (lo < hi) - { - i = (lo + hi) / 2; - - if (DECL_NAME (fields[i]) > name) - hi = i; - else if (DECL_NAME (fields[i]) < name) - lo = i + 1; - else - { - field = NULL_TREE; - - /* We might have a nested class and a field with the - same name; we sorted them appropriately via - field_decl_cmp, so just look for the first or last - field with this name. */ - if (want_type) - { - do - field = fields[i--]; - while (i >= lo && DECL_NAME (fields[i]) == name); - if (!DECL_DECLARES_TYPE_P (field)) - field = NULL_TREE; - } - else - { - do - field = fields[i++]; - while (i < hi && DECL_NAME (fields[i]) == name); - } - - if (field) - { - field = strip_using_decl (field); - if (is_overloaded_fn (field)) - field = NULL_TREE; - } - - return field; - } - } - return NULL_TREE; - } - - field = TYPE_FIELDS (type); - - for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) - { - tree decl = field; - - if (DECL_DECLARES_FUNCTION_P (decl)) - /* Functions are kep separately, at the moment. */ - continue; - - gcc_assert (DECL_P (field)); - if (DECL_NAME (field) == NULL_TREE - && ANON_AGGR_TYPE_P (TREE_TYPE (field))) - { - tree temp = lookup_field_1 (TREE_TYPE (field), name, want_type); - if (temp) - return temp; - } - - if (TREE_CODE (decl) == USING_DECL - && DECL_NAME (decl) == name) - { - decl = strip_using_decl (decl); - if (is_overloaded_fn (decl)) - continue; - } - - if (DECL_NAME (decl) == name - && (!want_type || DECL_DECLARES_TYPE_P (decl))) - return decl; - } - - /* We used to special-case vptr_identifier. Make sure it's not - special any more. */ - gcc_assert (name != vptr_identifier || !TYPE_VFIELD (type)); - - return NULL_TREE; -} - /* Return the FUNCTION_DECL, RECORD_TYPE, UNION_TYPE, or NAMESPACE_DECL corresponding to the innermost non-block scope. */ @@ -1454,158 +1354,6 @@ lookup_fnfields (tree xbasetype, tree name, int protect) return rval; } -/* Return the conversion operators in CLASS_TYPE corresponding to - "operator TYPE ()". Only CLASS_TYPE itself is searched; this - routine does not scan the base classes of CLASS_TYPE. */ - -static tree -lookup_conversion_operator (tree class_type, tree type) -{ - tree tpls = NULL_TREE; - - if (TYPE_HAS_CONVERSION (class_type)) - { - tree fns; - vec *methods = CLASSTYPE_METHOD_VEC (class_type); - - for (int i = CLASSTYPE_FIRST_CONVERSION_SLOT; - vec_safe_iterate (methods, i, &fns); ++i) - { - /* 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 (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; - } - } - - return tpls; -} - -/* TYPE is a class type. Return the member functions in the method - vector with name NAME. Does not lazily declare implicitly-declared - member functions. */ - -tree -lookup_fnfields_slot_nolazy (tree type, tree name) -{ - vec *method_vec = CLASSTYPE_METHOD_VEC (type); - if (!method_vec) - return NULL_TREE; - - if (IDENTIFIER_CONV_OP_P (name)) - return lookup_conversion_operator (type, TREE_TYPE (name)); - - /* Skip the conversion operators. */ - int i; - tree fns; - for (i = CLASSTYPE_FIRST_CONVERSION_SLOT; - vec_safe_iterate (method_vec, i, &fns); - ++i) - if (!DECL_CONV_FN_P (OVL_FIRST (fns))) - break; - - /* If the type is complete, use binary search. */ - if (COMPLETE_TYPE_P (type)) - { - int lo; - int hi; - - lo = i; - hi = method_vec->length (); - while (lo < hi) - { - i = (lo + hi) / 2; - - fns = (*method_vec)[i]; - tree fn_name = OVL_NAME (fns); - if (fn_name > name) - hi = i; - else if (fn_name < name) - lo = i + 1; - else - return fns; - } - } - else - for (; vec_safe_iterate (method_vec, i, &fns); ++i) - { - if (OVL_NAME (fns) == name) - return fns; - } - - return NULL_TREE; -} - -/* TYPE is a class type. Return the overloads in - the method vector with name NAME. Lazily create ctors etc. */ - -tree -lookup_fnfields_slot (tree type, tree name) -{ - type = complete_type (type); - - if (COMPLETE_TYPE_P (type)) - { - if (IDENTIFIER_CTOR_P (name)) - { - if (CLASSTYPE_LAZY_DEFAULT_CTOR (type)) - lazily_declare_fn (sfk_constructor, type); - if (CLASSTYPE_LAZY_COPY_CTOR (type)) - lazily_declare_fn (sfk_copy_constructor, type); - if (CLASSTYPE_LAZY_MOVE_CTOR (type)) - lazily_declare_fn (sfk_move_constructor, type); - } - else if (name == cp_assignment_operator_id (NOP_EXPR)) - { - if (CLASSTYPE_LAZY_COPY_ASSIGN (type)) - lazily_declare_fn (sfk_copy_assignment, type); - if (CLASSTYPE_LAZY_MOVE_ASSIGN (type)) - lazily_declare_fn (sfk_move_assignment, type); - } - else if (IDENTIFIER_DTOR_P (name)) - { - if (CLASSTYPE_LAZY_DESTRUCTOR (type)) - lazily_declare_fn (sfk_destructor, type); - } - } - - return lookup_fnfields_slot_nolazy (type, name); -} - -/* Collect all the conversion operators of KLASS. */ - -tree -lookup_all_conversions (tree klass) -{ - tree lkp = NULL_TREE; - - if (vec *methods = CLASSTYPE_METHOD_VEC (klass)) - { - tree ovl; - for (int idx = CLASSTYPE_FIRST_CONVERSION_SLOT; - methods->iterate (idx, &ovl); ++idx) - { - if (!DECL_CONV_FN_P (OVL_FIRST (ovl))) - /* There are no more conversion functions. */ - break; - - lkp = lookup_add (ovl, lkp); - } - } - - return lkp; -} - /* DECL is the result of a qualified name lookup. QUALIFYING_SCOPE is the class or namespace used to qualify the name. CONTEXT_CLASS is the class corresponding to the object in which DECL will be used. -- 2.30.2