diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2022-04-29 17:54:39 +0100 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2022-04-29 17:54:39 +0100 |
commit | 3e5f7ca352c26a222bb588741b7c700a3052a372 (patch) | |
tree | 283aec084274668fe34c23c49ab2999390ed9778 /gcc/cp/name-lookup.cc | |
parent | 2ce0608ca3dca30518bec525c435f7bc4d7f9b70 (diff) | |
parent | b85e79dce149df68b92ef63ca2a40ff1dfa61396 (diff) | |
download | gcc-3e5f7ca352c26a222bb588741b7c700a3052a372.tar.gz |
Merge master r12-8312.devel/c++-coroutines
* Merge master r12-8312-gb85e79dce149.
Diffstat (limited to 'gcc/cp/name-lookup.cc')
-rw-r--r-- | gcc/cp/name-lookup.cc | 95 |
1 files changed, 55 insertions, 40 deletions
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index d16c577c029..7b0638d3166 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -429,7 +429,7 @@ class name_lookup { public: typedef std::pair<tree, tree> using_pair; - typedef vec<using_pair, va_heap, vl_embed> using_queue; + typedef auto_vec<using_pair, 16> using_queue; public: tree name; /* The identifier being looked for. */ @@ -528,16 +528,8 @@ private: bool search_usings (tree scope); private: - using_queue *queue_namespace (using_queue *queue, int depth, tree scope); - using_queue *do_queue_usings (using_queue *queue, int depth, - vec<tree, va_gc> *usings); - using_queue *queue_usings (using_queue *queue, int depth, - vec<tree, va_gc> *usings) - { - if (usings) - queue = do_queue_usings (queue, depth, usings); - return queue; - } + void queue_namespace (using_queue& queue, int depth, tree scope); + void queue_usings (using_queue& queue, int depth, vec<tree, va_gc> *usings); private: void add_fns (tree); @@ -1084,39 +1076,35 @@ name_lookup::search_qualified (tree scope, bool usings) /* Add SCOPE to the unqualified search queue, recursively add its inlines and those via using directives. */ -name_lookup::using_queue * -name_lookup::queue_namespace (using_queue *queue, int depth, tree scope) +void +name_lookup::queue_namespace (using_queue& queue, int depth, tree scope) { if (see_and_mark (scope)) - return queue; + return; /* Record it. */ tree common = scope; while (SCOPE_DEPTH (common) > depth) common = CP_DECL_CONTEXT (common); - vec_safe_push (queue, using_pair (common, scope)); + queue.safe_push (using_pair (common, scope)); /* Queue its inline children. */ if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope)) for (unsigned ix = inlinees->length (); ix--;) - queue = queue_namespace (queue, depth, (*inlinees)[ix]); + queue_namespace (queue, depth, (*inlinees)[ix]); /* Queue its using targets. */ - queue = queue_usings (queue, depth, NAMESPACE_LEVEL (scope)->using_directives); - - return queue; + queue_usings (queue, depth, NAMESPACE_LEVEL (scope)->using_directives); } /* Add the namespaces in USINGS to the unqualified search queue. */ -name_lookup::using_queue * -name_lookup::do_queue_usings (using_queue *queue, int depth, - vec<tree, va_gc> *usings) +void +name_lookup::queue_usings (using_queue& queue, int depth, vec<tree, va_gc> *usings) { - for (unsigned ix = usings->length (); ix--;) - queue = queue_namespace (queue, depth, (*usings)[ix]); - - return queue; + if (usings) + for (unsigned ix = usings->length (); ix--;) + queue_namespace (queue, depth, (*usings)[ix]); } /* Unqualified namespace lookup in SCOPE. @@ -1128,15 +1116,12 @@ name_lookup::do_queue_usings (using_queue *queue, int depth, bool name_lookup::search_unqualified (tree scope, cp_binding_level *level) { - /* Make static to avoid continual reallocation. We're not - recursive. */ - static using_queue *queue = NULL; + using_queue queue; bool found = false; - int length = vec_safe_length (queue); /* Queue local using-directives. */ for (; level->kind != sk_namespace; level = level->level_chain) - queue = queue_usings (queue, SCOPE_DEPTH (scope), level->using_directives); + queue_usings (queue, SCOPE_DEPTH (scope), level->using_directives); for (; !found; scope = CP_DECL_CONTEXT (scope)) { @@ -1144,19 +1129,19 @@ name_lookup::search_unqualified (tree scope, cp_binding_level *level) int depth = SCOPE_DEPTH (scope); /* Queue namespaces reachable from SCOPE. */ - queue = queue_namespace (queue, depth, scope); + queue_namespace (queue, depth, scope); /* Search every queued namespace where SCOPE is the common ancestor. Adjust the others. */ - unsigned ix = length; + unsigned ix = 0; do { - using_pair &pair = (*queue)[ix]; + using_pair &pair = queue[ix]; while (pair.first == scope) { found |= search_namespace_only (pair.second); - pair = queue->pop (); - if (ix == queue->length ()) + pair = queue.pop (); + if (ix == queue.length ()) goto done; } /* The depth is the same as SCOPE, find the parent scope. */ @@ -1164,7 +1149,7 @@ name_lookup::search_unqualified (tree scope, cp_binding_level *level) pair.first = CP_DECL_CONTEXT (pair.first); ix++; } - while (ix < queue->length ()); + while (ix < queue.length ()); done:; if (scope == global_namespace) break; @@ -1181,9 +1166,6 @@ name_lookup::search_unqualified (tree scope, cp_binding_level *level) dedup (false); - /* Restore to incoming length. */ - vec_safe_truncate (queue, length); - return found; } @@ -5916,6 +5898,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp) tree found = NULL_TREE; bool hidden_p = false; + bool saw_template = false; for (lkp_iterator iter (old); iter; ++iter) { @@ -5940,6 +5923,20 @@ set_decl_namespace (tree decl, tree scope, bool friendp) found = ofn; hidden_p = iter.hidden_p (); } + else if (TREE_CODE (decl) == FUNCTION_DECL + && TREE_CODE (ofn) == TEMPLATE_DECL) + saw_template = true; + } + + if (!found && friendp && saw_template) + { + /* "[if no non-template match is found,] each remaining function template + is replaced with the specialization chosen by deduction from the + friend declaration or discarded if deduction fails." + + So tell check_explicit_specialization to look for a match. */ + SET_DECL_IMPLICIT_INSTANTIATION (decl); + return; } if (found) @@ -8979,4 +8976,22 @@ cp_emit_debug_info_for_using (tree t, tree context) } } +/* True if D is a local declaration in dependent scope. Assumes that it is + (part of) the current lookup result for its name. */ + +bool +dependent_local_decl_p (tree d) +{ + if (!DECL_LOCAL_DECL_P (d)) + return false; + + cxx_binding *b = IDENTIFIER_BINDING (DECL_NAME (d)); + cp_binding_level *l = b->scope; + while (!l->this_entity) + l = l->level_chain; + return uses_template_parms (l->this_entity); +} + + + #include "gt-cp-name-lookup.h" |