This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Separate cxx_binding uses in name lookup


cxx_binding was being used for two purposes in name lookup: to be
passed between routines representing a found binding, and as a
persistent data structure holding the binding for a particular scope.
This patch splits the two.  It is mostly for code clarity; there might
be a small speed improvement, but I doubt it would be measurable.

Bootstrapped & tested on powerpc-darwin, for C and C++ languages.

-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/gcc-cp-scopebinding.patch=================
2004-05-14  Geoffrey Keating  <geoffk@apple.com>

	* name-lookup.c (struct scope_binding): New.
	(EMPTY_SCOPE_BINDING): New.
	(lookup_using_namespace): Take a scope_binding instead of a
	cxx_binding.
	(qualified_lookup_using_namespace): Likewise.
	(cxx_binding_clear): Delete.
	(do_nonmember_using_decl): Use a scope_binding instead of a
	cxx_binding.
	(lookup_tag): Don't call select_decl.
	(ambiguous_decl): Don't return anything (and change callers to match).
	Take a scope_binding as the second parameter.
	(lookup_namespace_name): Use a scope_binding instead of a
	cxx_binding.
	(unqualified_namespace_lookup): Likewise.
	(lookup_qualified_name): Likewise.
	(select_decl): Take a scope_binding instead of a cxx_binding.
	Use macros rather than hand-coding tests for type-ness.

Index: name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.51
diff -u -p -u -p -r1.51 name-lookup.c
--- name-lookup.c	22 Apr 2004 05:10:21 -0000	1.51
+++ name-lookup.c	14 May 2004 22:30:23 -0000
@@ -32,14 +32,23 @@ Boston, MA 02111-1307, USA.  */
 #include "diagnostic.h"
 #include "debug.h"
 
+/* The bindings for a particular name in a particular scope.  */
+
+struct scope_binding {
+  tree value;
+  tree type;
+};
+#define EMPTY_SCOPE_BINDING { NULL_TREE, NULL_TREE }
+
 static cxx_scope *innermost_nonclass_level (void);
-static tree select_decl (cxx_binding *, int);
+static tree select_decl (const struct scope_binding *, int);
 static cxx_binding *binding_for_name (cxx_scope *, tree);
 static tree lookup_name_current_level (tree);
 static tree push_overloaded_decl (tree, int);
-static bool lookup_using_namespace (tree, cxx_binding *, tree,
+static bool lookup_using_namespace (tree, struct scope_binding *, tree,
                                     tree, int);
-static bool qualified_lookup_using_namespace (tree, tree, cxx_binding *, int);
+static bool qualified_lookup_using_namespace (tree, tree,
+					      struct scope_binding *, int);
 static tree lookup_type_current_level (tree);
 static tree push_using_directive (tree);
 static void cp_emit_debug_info_for_using (tree, tree);
@@ -319,9 +328,6 @@ binding_table_foreach (binding_table tab
 
 static GTY((deletable)) cxx_binding *free_bindings;
 
-/* Zero out a cxx_binding pointed to by B.  */
-#define cxx_binding_clear(B) memset ((B), 0, sizeof (cxx_binding))
-
 /* (GC)-allocate a binding object with VALUE and TYPE member initialized.  */
 
 static cxx_binding *
@@ -2116,10 +2122,9 @@ static void
 do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
                          tree *newval, tree *newtype)
 {
-  cxx_binding decls;
+  struct scope_binding decls = EMPTY_SCOPE_BINDING;
 
   *newval = *newtype = NULL_TREE;
-  cxx_binding_clear (&decls);
   if (!qualified_lookup_using_namespace (name, scope, &decls, 0))
     /* Lookup error */
     return;
@@ -2362,23 +2367,24 @@ lookup_tag (enum tree_code form, tree na
 	  {
             cxx_binding *binding =
               cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (tail), name);
-	    tree old;
-
-	    /* If we just skipped past a template parameter level,
-	       even though THISLEVEL_ONLY, and we find a template
-	       class declaration, then we use the _TYPE node for the
-	       template.  See the example below.  */
-	    if (thislevel_only && !allow_template_parms_p
-		&& binding && binding->value
-		&& DECL_CLASS_TEMPLATE_P (binding->value))
-	      old = binding->value;
-	    else if (binding)
-	      old = select_decl (binding, LOOKUP_PREFER_TYPES);
-            else
-              old = NULL_TREE;
 
-	    if (old)
+	    if (binding && (binding->type
+			    || (binding->value 
+				&& DECL_DECLARES_TYPE_P (binding->value))))
 	      {
+		tree old;
+		
+		/* If we just skipped past a template parameter level,
+		   even though THISLEVEL_ONLY, and we find a template
+		   class declaration, then we use the _TYPE node for the
+		   template.  See the example below.  */
+		if (thislevel_only && !allow_template_parms_p
+		    && binding->value
+		    && DECL_CLASS_TEMPLATE_P (binding->value))
+		  old = binding->value;
+		else
+		  old = binding->type ? binding->type : binding->value;
+
 		/* We've found something at this binding level.  If it is
 		   a typedef, extract the tag it refers to.  Lookup fails
 		   if the typedef doesn't refer to a taggable type.  */
@@ -3493,8 +3499,9 @@ merge_functions (tree s1, tree s2)
    XXX In what way should I treat extern declarations?
    XXX I don't want to repeat the entire duplicate_decls here */
 
-static cxx_binding *
-ambiguous_decl (tree name, cxx_binding *old, cxx_binding *new, int flags)
+static void
+ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
+		int flags)
 {
   tree val, type;
   my_friendly_assert (old != NULL, 393);
@@ -3568,7 +3575,6 @@ ambiguous_decl (tree name, cxx_binding *
           error ("%J  other type here", TYPE_MAIN_DECL (type));
         }
     }
-  return old;
 }
 
 /* Return the declarations that are members of the namespace NS.  */
@@ -3618,7 +3624,7 @@ lookup_namespace_name (tree namespace, t
 {
   tree val;
   tree template_id = NULL_TREE;
-  cxx_binding binding;
+  struct scope_binding binding = EMPTY_SCOPE_BINDING;
 
   timevar_push (TV_NAME_LOOKUP);
   my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370);
@@ -3648,7 +3654,6 @@ lookup_namespace_name (tree namespace, t
 
   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
 
-  cxx_binding_clear (&binding);
   if (!qualified_lookup_using_namespace (name, namespace, &binding, 0))
     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
@@ -3695,7 +3700,7 @@ lookup_namespace_name (tree namespace, t
 /* Select the right _DECL from multiple choices.  */
 
 static tree
-select_decl (cxx_binding *binding, int flags)
+select_decl (const struct scope_binding *binding, int flags)
 {
   tree val;
   val = binding->value;
@@ -3714,9 +3719,8 @@ select_decl (cxx_binding *binding, int f
   if (binding->type && (!val || (flags & LOOKUP_PREFER_TYPES)))
     val = binding->type;
   /* Don't return non-types if we really prefer types.  */
-  else if (val && LOOKUP_TYPES_ONLY (flags)  && TREE_CODE (val) != TYPE_DECL
-	   && (TREE_CODE (val) != TEMPLATE_DECL
-	       || !DECL_CLASS_TEMPLATE_P (val)))
+  else if (val && LOOKUP_TYPES_ONLY (flags) 
+	   && ! DECL_DECLARES_TYPE_P (val))
     val = NULL_TREE;
 
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
@@ -3733,10 +3737,9 @@ unqualified_namespace_lookup (tree name,
   tree siter;
   struct cp_binding_level *level;
   tree val = NULL_TREE;
-  cxx_binding binding;
+  struct scope_binding binding = EMPTY_SCOPE_BINDING;
 
   timevar_push (TV_NAME_LOOKUP);
-  cxx_binding_clear (&binding);
 
   for (; !val; scope = CP_DECL_CONTEXT (scope))
     {
@@ -3800,9 +3803,8 @@ lookup_qualified_name (tree scope, tree 
 
   if (TREE_CODE (scope) == NAMESPACE_DECL)
     {
-      cxx_binding binding;
+      struct scope_binding binding = EMPTY_SCOPE_BINDING;
 
-      cxx_binding_clear (&binding);
       flags |= LOOKUP_COMPLAIN;
       if (is_type_p)
 	flags |= LOOKUP_PREFER_TYPES;
@@ -3828,8 +3830,8 @@ lookup_qualified_name (tree scope, tree 
    Returns false on errors.  */
 
 static bool
-lookup_using_namespace (tree name, cxx_binding *val, tree usings, tree scope,
-                        int flags)
+lookup_using_namespace (tree name, struct scope_binding *val,
+			tree usings, tree scope, int flags)
 {
   tree iter;
   timevar_push (TV_NAME_LOOKUP);
@@ -3843,7 +3845,7 @@ lookup_using_namespace (tree name, cxx_b
           cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
         /* Resolve ambiguities.  */
         if (val1)
-          val = ambiguous_decl (name, val, val1, flags);
+          ambiguous_decl (name, val, val1, flags);
       }
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
 }
@@ -3854,8 +3856,8 @@ lookup_using_namespace (tree name, cxx_b
    or false on error.  */
 
 static bool
-qualified_lookup_using_namespace (tree name, tree scope, cxx_binding *result,
-                                  int flags)
+qualified_lookup_using_namespace (tree name, tree scope,
+				  struct scope_binding *result, int flags)
 {
   /* Maintain a list of namespaces visited...  */
   tree seen = NULL_TREE;
@@ -3872,7 +3874,7 @@ qualified_lookup_using_namespace (tree n
 	cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
       seen = tree_cons (scope, NULL_TREE, seen);
       if (binding)
-        result = ambiguous_decl (name, result, binding, flags);
+        ambiguous_decl (name, result, binding, flags);
 
       /* Consider strong using directives always, and non-strong ones
 	 if we haven't found a binding yet.  ??? Shouldn't we consider
============================================================


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]