2017-08-23 Nathan Sidwell <nathan@acm.org>
+ * 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.
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,
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<tree, va_gc> *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<tree, va_gc> *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<tree, va_gc> *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. */
current_function_decl = function_decl;
return x;
}
-
+
/* Inject X into the local scope just before the function parms. */
tree
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 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);
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. */
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<tree, va_gc> *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<tree, va_gc> *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<tree, va_gc> *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.