summaryrefslogtreecommitdiff
path: root/gcc/cp/search.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/search.c')
-rw-r--r--gcc/cp/search.c233
1 files changed, 107 insertions, 126 deletions
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 00f895c5d7d..469a88b4c6f 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -444,6 +444,10 @@ lookup_field_1 (tree type, tree name, bool want_type)
{
tree decl = field;
+ if (DECL_DECLARES_FUNCTION_P (decl))
+ /* Functions are kep separately, at the moment. */
+ continue;
+
if (GATHER_STATISTICS)
n_fields_searched++;
@@ -507,10 +511,13 @@ current_scope (void)
&& same_type_p (DECL_FRIEND_CONTEXT (current_function_decl),
current_class_type))))
return current_function_decl;
+
if (current_class_type)
return current_class_type;
+
if (current_function_decl)
return current_function_decl;
+
return current_namespace;
}
@@ -1523,86 +1530,67 @@ lookup_fnfields (tree xbasetype, tree name, int protect)
return rval;
}
-/* Return the index in the CLASSTYPE_METHOD_VEC for CLASS_TYPE
- corresponding to "operator TYPE ()", or -1 if there is no such
- operator. Only CLASS_TYPE itself is searched; this routine does
- not scan the base classes of CLASS_TYPE. */
+/* 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 int
+static tree
lookup_conversion_operator (tree class_type, tree type)
{
- int tpl_slot = -1;
+ tree tpls = NULL_TREE;
if (TYPE_HAS_CONVERSION (class_type))
{
- int i;
- tree fn;
+ tree fns;
vec<tree, va_gc> *methods = CLASSTYPE_METHOD_VEC (class_type);
- for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
- vec_safe_iterate (methods, i, &fn); ++i)
+ 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. */
- fn = OVL_FIRST (fn);
+ 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. */
- tpl_slot = i;
+ tpls = fns;
else if (same_type_p (DECL_CONV_FN_TYPE (fn), type))
- return i;
+ return fns;
}
}
- return tpl_slot;
+ return tpls;
}
-/* TYPE is a class type. Return the index of the fields within
- the method vector with name NAME, or -1 if no such field exists.
- Does not lazily declare implicitly-declared member functions. */
+/* TYPE is a class type. Return the member functions in the method
+ vector with name NAME. Does not lazily declare implicitly-declared
+ member functions. */
-static int
-lookup_fnfields_idx_nolazy (tree type, tree name)
+tree
+lookup_fnfields_slot_nolazy (tree type, tree name)
{
- vec<tree, va_gc> *method_vec;
- tree fn;
- size_t i;
-
- if (!CLASS_TYPE_P (type))
- return -1;
-
- method_vec = CLASSTYPE_METHOD_VEC (type);
+ vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (type);
if (!method_vec)
- return -1;
+ return NULL_TREE;
if (GATHER_STATISTICS)
n_calls_lookup_fnfields_1++;
- /* Constructors are first... */
- if (name == ctor_identifier)
- {
- fn = CLASSTYPE_CONSTRUCTORS (type);
- return fn ? CLASSTYPE_CONSTRUCTOR_SLOT : -1;
- }
- /* and destructors are second. */
- if (name == dtor_identifier)
- {
- fn = CLASSTYPE_DESTRUCTORS (type);
- return fn ? CLASSTYPE_DESTRUCTOR_SLOT : -1;
- }
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, &fn);
+ vec_safe_iterate (method_vec, i, &fns);
++i)
- if (!DECL_CONV_FN_P (OVL_FIRST (fn)))
+ if (!DECL_CONV_FN_P (OVL_FIRST (fns)))
break;
/* If the type is complete, use binary search. */
@@ -1620,42 +1608,39 @@ lookup_fnfields_idx_nolazy (tree type, tree name)
if (GATHER_STATISTICS)
n_outer_fields_searched++;
- tree tmp = (*method_vec)[i];
- tmp = OVL_NAME (tmp);
- if (tmp > name)
+ fns = (*method_vec)[i];
+ tree fn_name = OVL_NAME (fns);
+ if (fn_name > name)
hi = i;
- else if (tmp < name)
+ else if (fn_name < name)
lo = i + 1;
else
- return i;
+ return fns;
}
}
else
- for (; vec_safe_iterate (method_vec, i, &fn); ++i)
+ for (; vec_safe_iterate (method_vec, i, &fns); ++i)
{
if (GATHER_STATISTICS)
n_outer_fields_searched++;
- if (OVL_NAME (fn) == name)
- return i;
+ if (OVL_NAME (fns) == name)
+ return fns;
}
- return -1;
+ return NULL_TREE;
}
-/* TYPE is a class type. Return the index of the fields within
- the method vector with name NAME, or -1 if no such field exists. */
+/* TYPE is a class type. Return the overloads in
+ the method vector with name NAME. Lazily create ctors etc. */
-int
-lookup_fnfields_1 (tree type, tree name)
+tree
+lookup_fnfields_slot (tree type, tree name)
{
- if (!CLASS_TYPE_P (type))
- return -1;
+ type = complete_type (type);
if (COMPLETE_TYPE_P (type))
{
- if ((name == ctor_identifier
- || name == base_ctor_identifier
- || name == complete_ctor_identifier))
+ if (IDENTIFIER_CTOR_P (name))
{
if (CLASSTYPE_LAZY_DEFAULT_CTOR (type))
lazily_declare_fn (sfk_constructor, type);
@@ -1671,55 +1656,40 @@ lookup_fnfields_1 (tree type, tree name)
if (CLASSTYPE_LAZY_MOVE_ASSIGN (type))
lazily_declare_fn (sfk_move_assignment, type);
}
- else if ((name == dtor_identifier
- || name == base_dtor_identifier
- || name == complete_dtor_identifier
- || name == deleting_dtor_identifier)
- && CLASSTYPE_LAZY_DESTRUCTOR (type))
- lazily_declare_fn (sfk_destructor, type);
+ else if (IDENTIFIER_DTOR_P (name))
+ {
+ if (CLASSTYPE_LAZY_DESTRUCTOR (type))
+ lazily_declare_fn (sfk_destructor, type);
+ }
}
- return lookup_fnfields_idx_nolazy (type, name);
+ return lookup_fnfields_slot_nolazy (type, name);
}
-/* TYPE is a class type. Return the field within the method vector with
- name NAME, or NULL_TREE if no such field exists. */
+/* Collect all the conversion operators of KLASS. */
tree
-lookup_fnfields_slot (tree type, tree name)
+lookup_all_conversions (tree klass)
{
- int ix = lookup_fnfields_1 (complete_type (type), name);
- if (ix < 0)
- return NULL_TREE;
- return (*CLASSTYPE_METHOD_VEC (type))[ix];
-}
+ tree lkp = NULL_TREE;
-/* As above, but avoid lazily declaring functions. */
-
-tree
-lookup_fnfields_slot_nolazy (tree type, tree name)
-{
- int ix = lookup_fnfields_idx_nolazy (complete_type (type), name);
- if (ix < 0)
- return NULL_TREE;
- return (*CLASSTYPE_METHOD_VEC (type))[ix];
-}
-
-/* Like lookup_fnfields_1, except that the name is extracted from
- FUNCTION, which is a FUNCTION_DECL or a TEMPLATE_DECL. */
+ 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;
-int
-class_method_index_for_fn (tree class_type, tree function)
-{
- gcc_assert (DECL_DECLARES_FUNCTION_P (function));
+ lkp = lookup_add (ovl, lkp);
+ }
+ }
- return lookup_fnfields_1 (class_type,
- DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
- DECL_DESTRUCTOR_P (function) ? dtor_identifier :
- DECL_NAME (function));
+ 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.
@@ -2415,37 +2385,26 @@ look_for_overrides (tree type, tree fndecl)
tree
look_for_overrides_here (tree type, tree fndecl)
{
- int ix;
+ tree ovl = lookup_fnfields_slot (type, DECL_NAME (fndecl));
- /* If there are no methods in TYPE (meaning that only implicitly
- declared methods will ever be provided for TYPE), then there are
- no virtual functions. */
- if (!CLASSTYPE_METHOD_VEC (type))
- return NULL_TREE;
-
- if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fndecl))
- ix = CLASSTYPE_DESTRUCTOR_SLOT;
- else
- ix = lookup_fnfields_1 (type, DECL_NAME (fndecl));
- if (ix >= 0)
- for (ovl_iterator iter ((*CLASSTYPE_METHOD_VEC (type))[ix]); iter; ++iter)
- {
- tree fn = *iter;
+ for (ovl_iterator iter (ovl); iter; ++iter)
+ {
+ tree fn = *iter;
- if (!DECL_VIRTUAL_P (fn))
- /* Not a virtual. */;
- else if (DECL_CONTEXT (fn) != type)
- /* Introduced with a using declaration. */;
- else if (DECL_STATIC_FUNCTION_P (fndecl))
- {
- tree btypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
- tree dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
- if (compparms (TREE_CHAIN (btypes), dtypes))
- return fn;
- }
- else if (same_signature_p (fndecl, fn))
- return fn;
- }
+ if (!DECL_VIRTUAL_P (fn))
+ /* Not a virtual. */;
+ else if (DECL_CONTEXT (fn) != type)
+ /* Introduced with a using declaration. */;
+ else if (DECL_STATIC_FUNCTION_P (fndecl))
+ {
+ tree btypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ tree dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+ if (compparms (TREE_CHAIN (btypes), dtypes))
+ return fn;
+ }
+ else if (same_signature_p (fndecl, fn))
+ return fn;
+ }
return NULL_TREE;
}
@@ -2976,6 +2935,28 @@ binfo_via_virtual (tree binfo, tree limit)
return NULL_TREE;
}
+/* BINFO is for a base class in some hierarchy. Return true iff it is a
+ direct base. */
+
+bool
+binfo_direct_p (tree binfo)
+{
+ tree d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
+ if (BINFO_INHERITANCE_CHAIN (d_binfo))
+ /* A second inheritance chain means indirect. */
+ return false;
+ if (!BINFO_VIRTUAL_P (binfo))
+ /* Non-virtual, so only one inheritance chain means direct. */
+ return true;
+ /* A virtual base looks like a direct base, so we need to look through the
+ direct bases to see if it's there. */
+ tree b_binfo;
+ for (int i = 0; BINFO_BASE_ITERATE (d_binfo, i, b_binfo); ++i)
+ if (b_binfo == binfo)
+ return true;
+ return false;
+}
+
/* BINFO is a base binfo in the complete type BINFO_TYPE (HERE).
Find the equivalent binfo within whatever graph HERE is located.
This is the inverse of original_binfo. */