2017-05-16 Nathan Sidwell <nathan@acm.org>
+ * cp-tree.h (class ovl_iterator, class lkp_iterator): New OVERLOAD
+ iterators.
+ (MAYBE_BASELINK_FUNCTIONS): New.
+ * constraint.cc (resolve_constraint_check): Use lkp_iterator.
+ * decl2.c (maybe_warn_sized_delete): Use ovl_iterator.
+ * lambda.c (maybe_generic_this_capture): Use lkp_iterator.
+ * method.c (inherited_ctor_binfo): Use ovl_iterator.
+ (binfo_inherited_from): Likewise.
+ * parser.c (lookup_literal_operator): Use lkp_iterator.
+ * pt.c (iterative_hash_template_arg): Use lkp_iterator.
+ (print_candidates_1): Likewise.
+ (determine_specialization): Likewise.
+ (resolve_overloaded_unification): Likewise.
+ (resolve_nondeduced_context): Likewise.
+ (type_dependent_expression_p): Likewise.
+ (dependent_template_p): Likewise.
+ * ptree.c (cxx_print_xnode): Likewise.
+ * semantics.c (omp_reduction_lookup): Use lkp_iterator.
+ (classtype_has_nothrow_assign_or_copy_p): Use ovl_iterator.
+ * typeck.c (check_template_keyword): Use lkp_iterator.
+
* cp-tree.h (OVL_FIRST, OVL_NAME): New.
(ovl_first): New.
* constexpr.c (function_concept_check): Use OVL_FIRST.
{
int nerrs = 0;
tree cands = NULL_TREE;
- for (tree p = ovl; p != NULL_TREE; p = OVL_NEXT (p))
+ for (lkp_iterator iter (ovl); iter; ++iter)
{
// Get the next template overload.
- tree tmpl = OVL_CURRENT (p);
+ tree tmpl = *iter;
if (TREE_CODE (tmpl) != TEMPLATE_DECL)
continue;
tree function;
};
+/* Iterator for a 1 dimensional overload. */
+
+class ovl_iterator
+{
+ tree ovl;
+
+ public:
+ ovl_iterator (tree o)
+ :ovl (o)
+ {}
+
+ ovl_iterator &operator= (const ovl_iterator &from)
+ {
+ ovl = from.ovl;
+
+ return *this;
+ }
+
+ public:
+ operator bool () const
+ {
+ return ovl;
+ }
+ ovl_iterator &operator++ ()
+ {
+ ovl = TREE_CODE (ovl) != OVERLOAD ? NULL_TREE : OVL_CHAIN (ovl);
+ return *this;
+ }
+ tree operator* () const
+ {
+ tree fn = TREE_CODE (ovl) != OVERLOAD ? ovl : OVL_FUNCTION (ovl);
+
+ /* Check this is not an unexpected 2-dimensional overload. */
+ gcc_checking_assert (TREE_CODE (fn) != OVERLOAD);
+
+ return fn;
+ }
+};
+
+/* Iterator over a (potentially) 2 dimensional overload, which is
+ produced by name lookup. */
+
+/* Note this is currently a placeholder, as the name-lookup changes
+ are not yet committed. */
+
+class lkp_iterator : public ovl_iterator
+{
+ typedef ovl_iterator parent;
+
+ public:
+ lkp_iterator (tree o)
+ : parent (o)
+ {
+ }
+};
+
struct GTY(()) tree_template_decl {
struct tree_decl_common common;
tree arguments;
a TEMPLATE_DECL, an OVERLOAD, or a TEMPLATE_ID_EXPR. */
#define BASELINK_FUNCTIONS(NODE) \
(((struct tree_baselink*) BASELINK_CHECK (NODE))->functions)
+/* If T is a BASELINK, grab the functions, otherwise just T, which is
+ expected to already be a (list of) functions. */
+#define MAYBE_BASELINK_FUNCTIONS(T) \
+ (BASELINK_P (T) ? BASELINK_FUNCTIONS (T) : T)
/* The BINFO in which the search for the functions indicated by this baselink
began. This base is used to determine the accessibility of functions
selected by overload resolution. */
tree sized = NULL_TREE;
tree unsized = NULL_TREE;
- for (tree ovl = IDENTIFIER_GLOBAL_VALUE (cp_operator_id (code));
- ovl; ovl = OVL_NEXT (ovl))
+ for (ovl_iterator iter (IDENTIFIER_GLOBAL_VALUE (cp_operator_id (code)));
+ iter; ++iter)
{
- tree fn = OVL_CURRENT (ovl);
+ tree fn = *iter;
/* We're only interested in usual deallocation functions. */
if (!usual_deallocation_fn_p (fn))
continue;
bool id_expr = TREE_CODE (fns) == TEMPLATE_ID_EXPR;
if (id_expr)
fns = TREE_OPERAND (fns, 0);
- for (; fns; fns = OVL_NEXT (fns))
- {
- tree fn = OVL_CURRENT (fns);
-
- if ((!id_expr || TREE_CODE (fn) == TEMPLATE_DECL)
- && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
- {
- /* Found a non-static member. Capture this. */
- lambda_expr_this_capture (lam, true);
- break;
- }
- }
+
+ for (lkp_iterator iter (fns); iter; ++iter)
+ if ((!id_expr || TREE_CODE (*iter) == TEMPLATE_DECL)
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (*iter))
+ {
+ /* Found a non-static member. Capture this. */
+ lambda_expr_this_capture (lam, true);
+ break;
+ }
}
}
return binfo;
tree results = NULL_TREE;
- for (; inh; inh = OVL_NEXT (inh))
+ for (ovl_iterator iter (inh); iter; ++iter)
{
- tree one = inherited_ctor_binfo_1 (binfo, OVL_CURRENT (inh));
+ tree one = inherited_ctor_binfo_1 (binfo, *iter);
if (!results)
results = one;
else if (one != results)
{
/* inh is an OVERLOAD if we inherited the same constructor along
multiple paths, check all of them. */
- for (; inh; inh = OVL_NEXT (inh))
+ for (ovl_iterator iter (inh); iter; ++iter)
{
- tree fn = OVL_CURRENT (inh);
+ tree fn = *iter;
tree base = DECL_CONTEXT (fn);
tree base_binfo = NULL_TREE;
for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
static tree
lookup_literal_operator (tree name, vec<tree, va_gc> *args)
{
- tree decl, fns;
+ tree decl;
decl = lookup_name (name);
if (!decl || !is_overloaded_fn (decl))
return error_mark_node;
- for (fns = decl; fns; fns = OVL_NEXT (fns))
+ for (lkp_iterator iter (decl); iter; ++iter)
{
unsigned int ix;
bool found = true;
- tree fn = OVL_CURRENT (fns);
+ tree fn = *iter;
tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
if (parmtypes != NULL_TREE)
{
return val;
case OVERLOAD:
- for (; arg; arg = OVL_NEXT (arg))
- val = iterative_hash_template_arg (OVL_CURRENT (arg), val);
+ for (lkp_iterator iter (arg); iter; ++iter)
+ val = iterative_hash_template_arg (*iter, val);
return val;
case CONSTRUCTOR:
for (; fns; fns = TREE_CHAIN (fns))
print_candidates_1 (TREE_VALUE (fns), str, more || TREE_CHAIN (fns));
else
- while (fns)
+ for (lkp_iterator iter (fns); iter;)
{
- tree cand = OVL_CURRENT (fns);
+ tree cand = *iter;
+ ++iter;
- fns = OVL_NEXT (fns);
const char *pfx = *str;
if (!pfx)
{
- if (more || fns)
+ if (more || iter)
pfx = _("candidates are:");
else
pfx = _("candidate is:");
if (targs != error_mark_node)
templates = tree_cons (targs, fns, templates);
}
- else for (; fns; fns = OVL_NEXT (fns))
+ else for (lkp_iterator iter (fns); iter; ++iter)
{
- tree fn = OVL_CURRENT (fns);
+ tree fn = *iter;
if (TREE_CODE (fn) == TEMPLATE_DECL)
{
tree expl_subargs = TREE_OPERAND (arg, 1);
arg = TREE_OPERAND (arg, 0);
- for (; arg; arg = OVL_NEXT (arg))
+ for (lkp_iterator iter (arg); iter; ++iter)
{
- tree fn = OVL_CURRENT (arg);
+ tree fn = *iter;
tree subargs, elem;
if (TREE_CODE (fn) != TEMPLATE_DECL)
not just the function on its own. */
return false;
else
- for (; arg; arg = OVL_NEXT (arg))
- if (try_one_overload (tparms, targs, tempargs, parm,
- TREE_TYPE (OVL_CURRENT (arg)),
- strict, sub_strict, addr_p, explain_p)
- && (!goodfn || !decls_match (goodfn, OVL_CURRENT (arg))))
- {
- goodfn = OVL_CURRENT (arg);
- ++good;
- }
+ for (lkp_iterator iter (arg); iter; ++iter)
+ {
+ tree fn = *iter;
+ if (try_one_overload (tparms, targs, tempargs, parm, TREE_TYPE (fn),
+ strict, sub_strict, addr_p, explain_p)
+ && (!goodfn || !decls_match (goodfn, fn)))
+ {
+ goodfn = fn;
+ ++good;
+ }
+ }
/* [temp.deduct.type] A template-argument can be deduced from a pointer
to function or pointer to member function argument if the set of
tree badfn = NULL_TREE;
tree badargs = NULL_TREE;
- for (; arg; arg = OVL_NEXT (arg))
+ for (lkp_iterator iter (arg); iter; ++iter)
{
- tree fn = OVL_CURRENT (arg);
+ tree fn = *iter;
tree subargs, elem;
if (TREE_CODE (fn) != TEMPLATE_DECL)
gcc_assert (TREE_CODE (expression) == OVERLOAD
|| TREE_CODE (expression) == FUNCTION_DECL);
- while (expression)
- {
- if (type_dependent_expression_p (OVL_CURRENT (expression)))
- return true;
- expression = OVL_NEXT (expression);
- }
+ for (lkp_iterator iter (expression); iter; ++iter)
+ if (type_dependent_expression_p (*iter))
+ return true;
+
return false;
}
{
if (TREE_CODE (tmpl) == OVERLOAD)
{
- while (tmpl)
- {
- if (dependent_template_p (OVL_CURRENT (tmpl)))
- return true;
- tmpl = OVL_NEXT (tmpl);
- }
+ for (lkp_iterator iter (tmpl); iter; ++iter)
+ if (dependent_template_p (*iter))
+ return true;
return false;
}
indent + 4);
break;
case OVERLOAD:
- print_node (file, "function", OVL_FUNCTION (node), indent+4);
- print_node (file, "chain", TREE_CHAIN (node), indent+4);
+ print_node (file, "name", OVL_NAME (node), indent+4);
+ for (lkp_iterator iter (node); iter; ++iter)
+ print_node (file, "function", *iter, indent+4);
break;
case TEMPLATE_PARM_INDEX:
print_node (file, "decl", TEMPLATE_PARM_DECL (node), indent+4);
type),
false, false);
tree fns = id;
- if (id && is_overloaded_fn (id))
- id = get_fns (id);
- for (; id; id = OVL_NEXT (id))
+ id = NULL_TREE;
+ if (fns && is_overloaded_fn (fns))
{
- tree fndecl = OVL_CURRENT (id);
- if (TREE_CODE (fndecl) == FUNCTION_DECL)
+ for (lkp_iterator iter (get_fns (fns)); iter; ++iter)
{
- tree argtype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
- if (same_type_p (TREE_TYPE (argtype), type))
- break;
+ tree fndecl = *iter;
+ if (TREE_CODE (fndecl) == FUNCTION_DECL)
+ {
+ tree argtype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
+ if (same_type_p (TREE_TYPE (argtype), type))
+ {
+ id = fndecl;
+ break;
+ }
+ }
+ }
+
+ if (id && BASELINK_P (fns))
+ {
+ if (baselinkp)
+ *baselinkp = fns;
+ else
+ baselink = fns;
}
}
- if (id && BASELINK_P (fns))
- {
- if (baselinkp)
- *baselinkp = fns;
- else
- baselink = fns;
- }
- if (id == NULL_TREE && CLASS_TYPE_P (type) && TYPE_BINFO (type))
+
+ if (!id && CLASS_TYPE_P (type) && TYPE_BINFO (type))
{
vec<tree> ambiguous = vNULL;
tree binfo = TYPE_BINFO (type), base_binfo, ret = NULL_TREE;
else
return false;
- for (; fns; fns = OVL_NEXT (fns))
+ for (ovl_iterator iter (fns); iter; ++iter)
{
- tree fn = OVL_CURRENT (fns);
+ tree fn = *iter;
if (assign_p)
{
permerror (input_location, "%qD is not a template", decl);
else
{
- tree fns;
- fns = decl;
- if (BASELINK_P (fns))
- fns = BASELINK_FUNCTIONS (fns);
- while (fns)
+ bool found = false;
+
+ for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (decl));
+ !found && iter; ++iter)
{
- tree fn = OVL_CURRENT (fns);
+ tree fn = *iter;
if (TREE_CODE (fn) == TEMPLATE_DECL
- || TREE_CODE (fn) == TEMPLATE_ID_EXPR)
- break;
- if (TREE_CODE (fn) == FUNCTION_DECL
- && DECL_USE_TEMPLATE (fn)
- && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (fn)))
- break;
- fns = OVL_NEXT (fns);
+ || TREE_CODE (fn) == TEMPLATE_ID_EXPR
+ || (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_USE_TEMPLATE (fn)
+ && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (fn))))
+ found = true;
}
- if (!fns)
+ if (!found)
permerror (input_location, "%qD is not a template", decl);
}
}