aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2019-06-04 15:17:29 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2019-06-04 15:17:29 +0000
commit4ebcf1c2194569884858b65454ec6cf479efc680 (patch)
treeabd33982bfebde560ac0165472f1e68e75668731 /gcc
parent7b9202ea9ee9b9147a2c2e3f478f1f3eb0b5c174 (diff)
downloadgcc-4ebcf1c2194569884858b65454ec6cf479efc680.zip
gcc-4ebcf1c2194569884858b65454ec6cf479efc680.tar.gz
gcc-4ebcf1c2194569884858b65454ec6cf479efc680.tar.bz2
[C++ PATCH] structure tag lookup
https://gcc.gnu.org/ml/gcc-patches/2019-06/msg00179.html * name-lookup.c (lookup_type_scope_1): Reimplement, handle local and namespace scopes separately. From-SVN: r271912
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/name-lookup.c125
2 files changed, 60 insertions, 70 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 21b82df..c28faf9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2019-06-04 Nathan Sidwell <nathan@acm.org>
+
+ * name-lookup.c (lookup_type_scope_1): Reimplement, handle local
+ and namespace scopes separately.
+
2019-06-04 Harald van Dijk <harald@gigawatt.nl>
PR c++/60531 - Wrong error about unresolved overloaded function
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 0bea41f..632253a 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -6460,81 +6460,66 @@ lookup_name_prefer_type (tree name, int prefer_type)
static tree
lookup_type_scope_1 (tree name, tag_scope scope)
{
- cxx_binding *iter = NULL;
- tree val = NULL_TREE;
- cp_binding_level *level = NULL;
-
- /* Look in non-namespace scope first. */
- if (current_binding_level->kind != sk_namespace)
- iter = outer_binding (name, NULL, /*class_p=*/ true);
- for (; iter; iter = outer_binding (name, iter, /*class_p=*/ true))
- {
- /* Check if this is the kind of thing we're looking for.
- If SCOPE is TS_CURRENT, also make sure it doesn't come from
- base class. For ITER->VALUE, we can simply use
- INHERITED_VALUE_BINDING_P. For ITER->TYPE, we have to use
- our own check.
-
- We check ITER->TYPE before ITER->VALUE in order to handle
- typedef struct C {} C;
- correctly. */
-
- if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES)
- && (scope != ts_current
- || LOCAL_BINDING_P (iter)
- || DECL_CONTEXT (iter->type) == iter->scope->this_entity))
- val = iter->type;
- else if ((scope != ts_current
- || !INHERITED_VALUE_BINDING_P (iter))
- && qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
- val = iter->value;
-
- if (val)
- break;
- }
+ cp_binding_level *b = current_binding_level;
- /* Look in namespace scope. */
- if (val)
- level = iter->scope;
- else
- {
- tree ns = current_decl_namespace ();
+ if (b->kind != sk_namespace)
+ /* Look in non-namespace scopes. */
+ for (cxx_binding *iter = NULL;
+ (iter = outer_binding (name, iter, /*class_p=*/ true)); )
+ {
+ /* First check we're supposed to be looking in this scope --
+ if we're not, we're done. */
+ for (; b != iter->scope; b = b->level_chain)
+ if (!(b->kind == sk_cleanup
+ || b->kind == sk_template_parms
+ || b->kind == sk_function_parms
+ || (b->kind == sk_class
+ && scope == ts_within_enclosing_non_class)))
+ return NULL_TREE;
+
+ /* Check if this is the kind of thing we're looking for. If
+ SCOPE is TS_CURRENT, also make sure it doesn't come from
+ base class. For ITER->VALUE, we can simply use
+ INHERITED_VALUE_BINDING_P. For ITER->TYPE, we have to
+ use our own check.
+
+ We check ITER->TYPE before ITER->VALUE in order to handle
+ typedef struct C {} C;
+ correctly. */
+ if (tree type = iter->type)
+ if ((scope != ts_current
+ || LOCAL_BINDING_P (iter)
+ || DECL_CONTEXT (type) == iter->scope->this_entity)
+ && qualify_lookup (iter->type, LOOKUP_PREFER_TYPES))
+ return iter->type;
+
+ if ((scope != ts_current
+ || !INHERITED_VALUE_BINDING_P (iter))
+ && qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
+ return iter->value;
+ }
- if (tree *slot = find_namespace_slot (ns, name))
- {
- /* If this is the kind of thing we're looking for, we're done. */
- if (tree type = MAYBE_STAT_TYPE (*slot))
- if (qualify_lookup (type, LOOKUP_PREFER_TYPES))
- val = type;
- if (!val)
- {
- if (tree decl = MAYBE_STAT_DECL (*slot))
- if (qualify_lookup (decl, LOOKUP_PREFER_TYPES))
- val = decl;
- }
- level = NAMESPACE_LEVEL (ns);
- }
- }
+ /* Now check if we can look in namespace scope. */
+ for (; b->kind != sk_namespace; b = b->level_chain)
+ if (!(b->kind == sk_cleanup
+ || b->kind == sk_template_parms
+ || b->kind == sk_function_parms
+ || (b->kind == sk_class
+ && scope == ts_within_enclosing_non_class)))
+ return NULL_TREE;
- /* Type found, check if it is in the allowed scopes, ignoring cleanup
- and template parameter scopes. */
- if (val)
+ /* Look in the innermost namespace. */
+ tree ns = b->this_entity;
+ if (tree *slot = find_namespace_slot (ns, name))
{
- cp_binding_level *b = current_binding_level;
- while (b)
- {
- if (level == b)
- return val;
+ /* If this is the kind of thing we're looking for, we're done. */
+ if (tree type = MAYBE_STAT_TYPE (*slot))
+ if (qualify_lookup (type, LOOKUP_PREFER_TYPES))
+ return type;
- if (b->kind == sk_cleanup || b->kind == sk_template_parms
- || b->kind == sk_function_parms)
- b = b->level_chain;
- else if (b->kind == sk_class
- && scope == ts_within_enclosing_non_class)
- b = b->level_chain;
- else
- break;
- }
+ if (tree decl = MAYBE_STAT_DECL (*slot))
+ if (qualify_lookup (decl, LOOKUP_PREFER_TYPES))
+ return decl;
}
return NULL_TREE;