From 3f267553fca2671ca4abb0dbbe3c9f625357edf0 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 16 May 2017 14:46:30 +0000 Subject: [PATCH] cp-tree.h (class ovl_iterator, [...]): New OVERLOAD iterators. * 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. From-SVN: r248112 --- gcc/cp/ChangeLog | 21 +++++++++++++++ gcc/cp/constraint.cc | 4 +-- gcc/cp/cp-tree.h | 60 +++++++++++++++++++++++++++++++++++++++++ gcc/cp/decl2.c | 6 ++--- gcc/cp/lambda.c | 21 +++++++-------- gcc/cp/method.c | 8 +++--- gcc/cp/parser.c | 6 ++--- gcc/cp/pt.c | 63 +++++++++++++++++++++----------------------- gcc/cp/ptree.c | 5 ++-- gcc/cp/semantics.c | 43 +++++++++++++++++------------- gcc/cp/typeck.c | 25 ++++++++---------- 11 files changed, 171 insertions(+), 91 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c094ea0d63e..4f7c8d41249 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,26 @@ 2017-05-16 Nathan Sidwell + * 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. diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 59b315159be..e3b876278d4 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -204,10 +204,10 @@ resolve_constraint_check (tree ovl, tree args) { 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; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8dee22f42f9..b81e94ddf9a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -636,6 +636,62 @@ struct GTY(()) tree_overload { 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; @@ -653,6 +709,10 @@ struct GTY(()) tree_template_decl { 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. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 4b99a8ebe8d..c1ac98098db 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4390,10 +4390,10 @@ maybe_warn_sized_delete (enum tree_code code) 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; diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 80643ea2bbc..9d7701fba9b 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -841,18 +841,15 @@ maybe_generic_this_capture (tree object, tree fns) 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; + } } } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index a9bc4907eb7..9898ff19089 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -538,9 +538,9 @@ inherited_ctor_binfo (tree binfo, tree fndecl) 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) @@ -593,9 +593,9 @@ binfo_inherited_from (tree binfo, tree init_binfo, tree inh) { /* 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++) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 99c742f72e9..7509dce7db0 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4061,16 +4061,16 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok, static tree lookup_literal_operator (tree name, vec *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) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index aa6af295c0f..142ed66ff38 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1746,8 +1746,8 @@ iterative_hash_template_arg (tree arg, hashval_t val) 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: @@ -1926,15 +1926,15 @@ print_candidates_1 (tree fns, char **str, bool more = false) 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:"); @@ -2102,9 +2102,9 @@ determine_specialization (tree template_id, 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) { @@ -19379,9 +19379,9 @@ resolve_overloaded_unification (tree tparms, 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) @@ -19420,15 +19420,17 @@ resolve_overloaded_unification (tree tparms, 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 @@ -19510,9 +19512,9 @@ resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain) 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) @@ -23926,12 +23928,10 @@ type_dependent_expression_p (tree expression) 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; } @@ -24284,12 +24284,9 @@ dependent_template_p (tree tmpl) { 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; } diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c index 109e41ad231..5c7548adbda 100644 --- a/gcc/cp/ptree.c +++ b/gcc/cp/ptree.c @@ -236,8 +236,9 @@ cxx_print_xnode (FILE *file, tree node, int indent) 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); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index d9e1ee39d61..ce2899b7aef 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5205,26 +5205,33 @@ omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp, 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 ambiguous = vNULL; tree binfo = TYPE_BINFO (type), base_binfo, ret = NULL_TREE; @@ -9062,9 +9069,9 @@ classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p) 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) { diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 6f15c9be07b..46a6bf8df35 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2628,23 +2628,20 @@ check_template_keyword (tree decl) 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); } } -- 2.30.2