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
This commit is contained in:
parent
3928bd5fc1
commit
9e931c2a28
@ -1,5 +1,17 @@
|
||||
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.
|
||||
|
@ -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,
|
||||
|
@ -1089,6 +1089,258 @@ lookup_arg_dependent (tree name, tree fns, vec<tree, va_gc> *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<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. */
|
||||
@ -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
|
||||
|
@ -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<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);
|
||||
|
252
gcc/cp/search.c
252
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<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.
|
||||
|
Loading…
Reference in New Issue
Block a user