public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ PATCH] structure tag lookup.
@ 2019-06-04 15:13 Nathan Sidwell
  2019-06-04 15:20 ` Marek Polacek
  0 siblings, 1 reply; 3+ messages in thread
From: Nathan Sidwell @ 2019-06-04 15:13 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 541 bytes --]

lookup of a structure tag, via xref tag, is rather confused, and I found 
myself wandering into that code.  We lookup a tag on the binding scopes, 
then if that fails we try the innermost enclosing namespace.  /Then/ we 
see if we were allowed to look at the scope we found something in.

I've reimplemented this so we stop looking when we reach a scope we're 
not to look in.  It also neatly separates the local binding-scope chain 
walking from the namespace lookup, which is the goal I had.

applying to trunk.

nathan
-- 
Nathan Sidwell

[-- Attachment #2: lkup.diff --]
[-- Type: text/x-patch, Size: 4731 bytes --]

2019-06-04  Nathan Sidwell  <nathan@acm.org>

	* name-lookup.c (lookup_type_scope_1): Reimplement, handle local
	and namespace scopes separately.

Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 271906)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -6461,79 +6461,64 @@ 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;
-    }
-
-  /* Look in namespace scope.  */
-  if (val)
-    level = iter->scope;
-  else
-    {
-      tree ns = current_decl_namespace ();
-
-      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);
-	}
-    }
+  cp_binding_level *b = current_binding_level;
 
-  /* Type found, check if it is in the allowed scopes, ignoring cleanup
-     and template parameter scopes.  */
-  if (val)
+  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;
+      }
+
+  /* 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;
+
+  /* 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 (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 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 (tree decl = MAYBE_STAT_DECL (*slot))
+	if (qualify_lookup (decl, LOOKUP_PREFER_TYPES))
+	  return decl;
     }
 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [C++ PATCH] structure tag lookup.
  2019-06-04 15:13 [C++ PATCH] structure tag lookup Nathan Sidwell
@ 2019-06-04 15:20 ` Marek Polacek
  2019-06-05 10:30   ` Nathan Sidwell
  0 siblings, 1 reply; 3+ messages in thread
From: Marek Polacek @ 2019-06-04 15:20 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On Tue, Jun 04, 2019 at 11:13:14AM -0400, Nathan Sidwell wrote:
> -  /* Type found, check if it is in the allowed scopes, ignoring cleanup
> -     and template parameter scopes.  */
> -  if (val)
> +  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;

[...]

> +  /* 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;

Looks like we could break that out into a new predicate function?
Something like allowed_scope_p?

Marek

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [C++ PATCH] structure tag lookup.
  2019-06-04 15:20 ` Marek Polacek
@ 2019-06-05 10:30   ` Nathan Sidwell
  0 siblings, 0 replies; 3+ messages in thread
From: Nathan Sidwell @ 2019-06-05 10:30 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

On 6/4/19 11:20 AM, Marek Polacek wrote:
> On Tue, Jun 04, 2019 at 11:13:14AM -0400, Nathan Sidwell wrote:

> [...]
> 
>> +  /* 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;
> 
> Looks like we could break that out into a new predicate function?
> Something like allowed_scope_p?

Yeah, I thought about that, but didn't think it worth the effort.

nathan

-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-06-05 10:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-04 15:13 [C++ PATCH] structure tag lookup Nathan Sidwell
2019-06-04 15:20 ` Marek Polacek
2019-06-05 10:30   ` Nathan Sidwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).