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]

C++ PATCH: Move more name lookup code to name-lookup.c


This patch moves more name lookup codes from cp/decl2.c to
cp/name-lookup.c.  Now, almost all non-class member lookup codes are
in cp/name-lookup.c, and you can admire the code duplication.
This enables future works for unifying, speeding up the lookup code.
The patch is straight.

Bootstrapped and regtested on an i686-pc-linux-gnu.
Installed as obvious.

-- Gaby

Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v
retrieving revision 1.3725
diff -p -r1.3725 ChangeLog
*** ChangeLog	13 Oct 2003 10:33:59 -0000	1.3725
--- ChangeLog	13 Oct 2003 12:56:04 -0000
***************
*** 1,5 ****
--- 1,44 ----
  2003-10-13  Gabriel Dos Reis  <gdr@integrable-solutions.net>
  
+ 	* name-lookup.h (cxx_scope_find_binding_for_name): Don't export.
+ 	(binding_for_name): Likewise.
+ 	(cxx_binding_clear): Move to name-lookup.c.
+ 	* name-lookup.c (cxx_scope_find_binding_for_name): Now static.
+ 	(binding_for_name): Likewise.
+ 	* decl2.c (is_ancestor): Move to name-lookup.c
+ 	(namespace_ancestor): Likewise.
+ 	(add_using_namespace): Likewise.
+ 	(ambiguous_decl): Likewise.
+ 	(lookup_using_namespace): Likewise.
+ 	(qualified_lookup_using_namespace): Likewise.
+ 	(set_decl_namespace): Likewise.
+ 	(decl_namespace): Likewise.
+ 	(current_decl_namespace): Likewise.
+ 	(push_decl_namespace): Likewise.
+ 	(pop_decl_namespace): Likewise.
+ 	(push_scope): Likewise.
+ 	(pop_scope): Likewise.
+ 	(struct arg_lookup): Likewise.
+ 	(arg_assoc): Likewise.
+ 	(arg_assoc_args): Likewise.
+ 	(arg_assoc_type): Likewise.
+ 	(add_function): Likewise.
+ 	(arg_assoc_namespace): Likewise.
+ 	(arg_assoc_class): Likewise.
+ 	(arg_assoc_template_arg): Likewise.
+ 	(do_namespace_alias): Likewise.
+ 	(validate_nonmember_using_decl): Likewise.
+ 	(do_nonmember_using_decl): Likewise.
+ 	(do_toplevel_using_decl): Likewise.
+ 	(do_local_using_decl): Likewise.
+ 	(do_class_using_decl): Likewise.
+ 	(do_using_directive): Likewise.
+ 	(constructor_name_full): Likewise.
+ 	(constructor_name): Likewise.
+ 	(constructor_name_p): Likewise.
+ 
+ 2003-10-13  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+ 
  	Break out decl.c (2/n) 
  	* name-lookup.c: Include diagnostic.h
  	(cxx_binding_free): Make static.
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.926
diff -p -r1.926 cp-tree.h
*** cp-tree.h	13 Oct 2003 10:26:36 -0000	1.926
--- cp-tree.h	13 Oct 2003 12:56:07 -0000
*************** extern void check_goto				(tree);
*** 3615,3625 ****
  extern void define_case_label			(void);
  extern tree make_typename_type			(tree, tree, tsubst_flags_t);
  extern tree make_unbound_class_template		(tree, tree, tsubst_flags_t);
- extern tree namespace_ancestor			(tree, tree);
- extern bool is_ancestor                         (tree, tree);
  extern tree check_for_out_of_scope_variable     (tree);
- extern bool lookup_using_namespace (tree, cxx_binding *, tree, tree, int, tree *);
- extern bool qualified_lookup_using_namespace (tree, tree, cxx_binding *, int);
  extern tree build_library_fn			(tree, tree);
  extern tree build_library_fn_ptr		(const char *, tree);
  extern tree build_cp_library_fn_ptr		(const char *, tree);
--- 3615,3621 ----
*************** extern tree grokfield (tree, tree, tree,
*** 3709,3717 ****
  extern tree grokbitfield (tree, tree, tree);
  extern tree groktypefield			(tree, tree);
  extern void cplus_decl_attributes (tree *, tree, int);
- extern tree constructor_name_full		(tree);
- extern tree constructor_name (tree);
- extern bool constructor_name_p                  (tree, tree);
  extern void defer_fn (tree);
  extern void finish_anon_union (tree);
  extern tree finish_table (tree, tree, tree, int);
--- 3705,3710 ----
*************** extern void import_export_decl (tree);
*** 3723,3742 ****
  extern void import_export_tinfo	(tree, tree, bool);
  extern tree build_cleanup			(tree);
  extern tree build_offset_ref_call_from_tree     (tree, tree);
- extern void set_decl_namespace (tree, tree, bool);
- extern tree current_decl_namespace              (void);
- extern void push_decl_namespace                 (tree);
- extern void pop_decl_namespace                  (void);
- extern void push_scope				(tree);
- extern void pop_scope				(tree);
- extern void do_namespace_alias (tree, tree);
- extern void do_toplevel_using_decl (tree);
- extern void do_local_using_decl (tree);
- extern tree do_class_using_decl (tree);
- extern void do_using_directive (tree);
  extern void check_default_args (tree);
  extern void mark_used (tree);
- extern tree lookup_arg_dependent (tree, tree, tree);
  extern void finish_static_data_member_decl (tree, tree, tree, int);
  extern tree cp_build_parm_decl (tree, tree);
  extern tree build_artificial_parm (tree, tree);
--- 3716,3723 ----
Index: decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.682
diff -p -r1.682 decl2.c
*** decl2.c	28 Sep 2003 04:37:40 -0000	1.682
--- decl2.c	13 Oct 2003 12:56:08 -0000
*************** typedef struct priority_info_s {
*** 64,79 ****
  static void mark_vtable_entries (tree);
  static void grok_function_init (tree, tree);
  static bool maybe_emit_vtables (tree);
- static void add_using_namespace (tree, tree, bool);
- static cxx_binding *ambiguous_decl (tree, cxx_binding *, cxx_binding *, int);
  static tree build_anon_union_vars (tree);
  static bool acceptable_java_type (tree);
  static tree start_objects (int, int);
  static void finish_objects (int, int, tree);
- static tree merge_functions (tree, tree);
- static tree decl_namespace (tree);
- static tree validate_nonmember_using_decl (tree, tree *, tree *);
- static void do_nonmember_using_decl (tree, tree, tree, tree, tree *, tree *);
  static tree start_static_storage_duration_function (unsigned);
  static void finish_static_storage_duration_function (tree);
  static priority_info get_priority_info (int);
--- 64,73 ----
*************** int at_eof;
*** 115,123 ****
  tree static_ctors;
  tree static_dtors;
  
- /* The :: namespace.  */
- 
- tree global_namespace;
  
  /* Incorporate `const' and `volatile' qualifiers for member functions.
     FUNCTION is a TYPE_DECL or a FUNCTION_DECL.
--- 109,114 ----
*************** cplus_decl_attributes (tree *decl, tree 
*** 1150,1207 ****
      SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
  }
  
- /* Return the name for the constructor (or destructor) for the
-    specified class TYPE.  When given a template, this routine doesn't
-    lose the specialization.  */
- 
- tree
- constructor_name_full (tree type)
- {
-   type = TYPE_MAIN_VARIANT (type);
-   if (CLASS_TYPE_P (type) && TYPE_WAS_ANONYMOUS (type) 
-       && TYPE_HAS_CONSTRUCTOR (type))
-     return DECL_NAME (OVL_CURRENT (CLASSTYPE_CONSTRUCTORS (type)));
-   else
-     return TYPE_IDENTIFIER (type);
- }
- 
- /* Return the name for the constructor (or destructor) for the
-    specified class.  When given a template, return the plain
-    unspecialized name.  */
- 
- tree
- constructor_name (tree type)
- {
-   tree name;
-   name = constructor_name_full (type);
-   if (IDENTIFIER_TEMPLATE (name))
-     name = IDENTIFIER_TEMPLATE (name);
-   return name;
- }
- 
- /* Returns TRUE if NAME is the name for the constructor for TYPE.  */
- 
- bool
- constructor_name_p (tree name, tree type)
- {
-   tree ctor_name;
- 
-   if (!name)
-     return false;
-   
-   if (TREE_CODE (name) != IDENTIFIER_NODE)
-     return false;
-   
-   ctor_name = constructor_name_full (type);
-   if (name == ctor_name)
-     return true;
-   if (IDENTIFIER_TEMPLATE (ctor_name)
-       && name == IDENTIFIER_TEMPLATE (ctor_name))
-     return true;
-   return false;
- }
- 
- 
  /* Defer the compilation of the FN until the end of compilation.  */
  
  void
--- 1141,1146 ----
*************** build_offset_ref_call_from_tree (tree fn
*** 3013,4127 ****
      return build_min_non_dep (CALL_EXPR, expr, orig_fn, orig_args);
    return expr;
  }
- 
- /* Returns true if ROOT (a namespace, class, or function) encloses
-    CHILD.  CHILD may be either a class type or a namespace.  */
- 
- bool
- is_ancestor (tree root, tree child)
- {
-   my_friendly_assert ((TREE_CODE (root) == NAMESPACE_DECL
- 		       || TREE_CODE (root) == FUNCTION_DECL
- 		       || CLASS_TYPE_P (root)), 20030307);
-   my_friendly_assert ((TREE_CODE (child) == NAMESPACE_DECL
- 		       || CLASS_TYPE_P (child)),
- 		      20030307);
-   
-   /* The global namespace encloses everything.  */
-   if (root == global_namespace)
-     return true;
- 
-   while (true)
-     {
-       /* If we've run out of scopes, stop.  */
-       if (!child)
- 	return false;
-       /* If we've reached the ROOT, it encloses CHILD.  */
-       if (root == child)
- 	return true;
-       /* Go out one level.  */
-       if (TYPE_P (child))
- 	child = TYPE_NAME (child);
-       child = DECL_CONTEXT (child);
-     }
- }
-   
- 
- /* Return the namespace that is the common ancestor 
-    of two given namespaces.  */
- 
- tree
- namespace_ancestor (tree ns1, tree ns2)
- {
-   timevar_push (TV_NAME_LOOKUP);
-   if (is_ancestor (ns1, ns2))
-     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ns1);
-   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
-                           namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2));
- }
- 
- /* Insert USED into the using list of USER. Set INDIRECT_flag if this
-    directive is not directly from the source. Also find the common
-    ancestor and let our users know about the new namespace */
- static void 
- add_using_namespace (tree user, tree used, bool indirect)
- {
-   tree t;
-   timevar_push (TV_NAME_LOOKUP);
-   /* Using oneself is a no-op.  */
-   if (user == used)
-     {
-       timevar_pop (TV_NAME_LOOKUP);
-       return;
-     }
-   my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380);
-   my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380);
-   /* Check if we already have this.  */
-   t = purpose_member (used, DECL_NAMESPACE_USING (user));
-   if (t != NULL_TREE)
-     {
-       if (!indirect)
- 	/* Promote to direct usage.  */
- 	TREE_INDIRECT_USING (t) = 0;
-       timevar_pop (TV_NAME_LOOKUP);
-       return;
-     }
- 
-   /* Add used to the user's using list.  */
-   DECL_NAMESPACE_USING (user) 
-     = tree_cons (used, namespace_ancestor (user, used), 
- 		 DECL_NAMESPACE_USING (user));
- 
-   TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
- 
-   /* Add user to the used's users list.  */
-   DECL_NAMESPACE_USERS (used)
-     = tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
- 
-   /* Recursively add all namespaces used.  */
-   for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
-     /* indirect usage */
-     add_using_namespace (user, TREE_PURPOSE (t), 1);
- 
-   /* Tell everyone using us about the new used namespaces.  */
-   for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t))
-     add_using_namespace (TREE_PURPOSE (t), used, 1);
-   timevar_pop (TV_NAME_LOOKUP);
- }
- 
- /* Combines two sets of overloaded functions into an OVERLOAD chain, removing
-    duplicates.  The first list becomes the tail of the result.
- 
-    The algorithm is O(n^2).  We could get this down to O(n log n) by
-    doing a sort on the addresses of the functions, if that becomes
-    necessary.  */
- 
- static tree
- merge_functions (tree s1, tree s2)
- {
-   for (; s2; s2 = OVL_NEXT (s2))
-     {
-       tree fn2 = OVL_CURRENT (s2);
-       tree fns1;
- 
-       for (fns1 = s1; fns1; fns1 = OVL_NEXT (fns1))
- 	{
- 	  tree fn1 = OVL_CURRENT (fns1);
- 
- 	  /* If the function from S2 is already in S1, there is no
- 	     need to add it again.  For `extern "C"' functions, we
- 	     might have two FUNCTION_DECLs for the same function, in
- 	     different namespaces; again, we only need one of them.  */
- 	  if (fn1 == fn2 
- 	      || (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2)
- 		  && DECL_NAME (fn1) == DECL_NAME (fn2)))
- 	    break;
- 	}
-       
-       /* If we exhausted all of the functions in S1, FN2 is new.  */
-       if (!fns1)
- 	s1 = build_overload (fn2, s1);
-     }
-   return s1;
- }
- 
- /* This should return an error not all definitions define functions.
-    It is not an error if we find two functions with exactly the
-    same signature, only if these are selected in overload resolution.
-    old is the current set of bindings, new the freshly-found binding.
-    XXX Do we want to give *all* candidates in case of ambiguity?
-    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)
- {
-   tree val, type;
-   my_friendly_assert (old != NULL, 393);
-   /* Copy the value.  */
-   val = new->value;
-   if (val)
-     switch (TREE_CODE (val))
-       {
-       case TEMPLATE_DECL:
-         /* If we expect types or namespaces, and not templates,
-            or this is not a template class.  */
-         if (LOOKUP_QUALIFIERS_ONLY (flags)
-             && !DECL_CLASS_TEMPLATE_P (val))
-           val = NULL_TREE;
-         break;
-       case TYPE_DECL:
-         if (LOOKUP_NAMESPACES_ONLY (flags))
-           val = NULL_TREE;
-         break;
-       case NAMESPACE_DECL:
-         if (LOOKUP_TYPES_ONLY (flags))
-           val = NULL_TREE;
-         break;
-       case FUNCTION_DECL:
-         /* Ignore built-in functions that are still anticipated.  */
-         if (LOOKUP_QUALIFIERS_ONLY (flags) || DECL_ANTICIPATED (val))
-           val = NULL_TREE;
-         break;
-       default:
-         if (LOOKUP_QUALIFIERS_ONLY (flags))
-           val = NULL_TREE;
-       }
-         
-   if (!old->value)
-     old->value = val;
-   else if (val && val != old->value)
-     {
-       if (is_overloaded_fn (old->value) && is_overloaded_fn (val))
-         old->value = merge_functions (old->value, val);
-       else
- 	{
- 	  /* Some declarations are functions, some are not.  */
-           if (flags & LOOKUP_COMPLAIN)
-             {
- 	      /* If we've already given this error for this lookup,
- 		 old->value is error_mark_node, so let's not
- 		 repeat ourselves.  */
- 	      if (old->value != error_mark_node)
- 		{
- 		  error ("use of `%D' is ambiguous", name);
- 		  cp_error_at ("  first declared as `%#D' here",
- 			       old->value);
- 		}
-               cp_error_at ("  also declared as `%#D' here", val);
-             }
- 	  old->value = error_mark_node;
- 	}
-     }
-   /* ... and copy the type.  */
-   type = new->type;
-   if (LOOKUP_NAMESPACES_ONLY (flags))
-     type = NULL_TREE;
-   if (!old->type)
-     old->type = type;
-   else if (type && old->type != type)
-     {
-       if (flags & LOOKUP_COMPLAIN)
-         {
-           error ("`%D' denotes an ambiguous type",name);
-           error ("%J  first type here", TYPE_MAIN_DECL (old->type));
-           error ("%J  other type here", TYPE_MAIN_DECL (type));
-         }
-     }
-   return old;
- }
- 
- /* Subroutine of unualified_namespace_lookup:
-    Add the bindings of NAME in used namespaces to VAL.
-    We are currently looking for names in namespace SCOPE, so we
-    look through USINGS for using-directives of namespaces
-    which have SCOPE as a common ancestor with the current scope.
-    Returns false on errors.  */
- 
- bool
- lookup_using_namespace (tree name, cxx_binding *val, tree usings, tree scope,
-                         int flags, tree *spacesp)
- {
-   tree iter;
-   timevar_push (TV_NAME_LOOKUP);
-   /* Iterate over all used namespaces in current, searching for using
-      directives of scope.  */
-   for (iter = usings; iter; iter = TREE_CHAIN (iter))
-     if (TREE_VALUE (iter) == scope)
-       {
-         tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
-         cxx_binding *val1 =
-           cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
-         if (spacesp)
-           *spacesp = tree_cons (used, NULL_TREE, *spacesp);
-         /* Resolve ambiguities.  */
-         if (val1)
-           val = ambiguous_decl (name, val, val1, flags);
-       }
-   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
- }
- 
- /* [namespace.qual]
-    Accepts the NAME to lookup and its qualifying SCOPE.
-    Returns the name/type pair found into the cxx_binding *RESULT,
-    or false on error.  */
- 
- bool
- qualified_lookup_using_namespace (tree name, tree scope, cxx_binding *result,
-                                   int flags)
- {
-   /* Maintain a list of namespaces visited...  */
-   tree seen = NULL_TREE;
-   /* ... and a list of namespace yet to see.  */
-   tree todo = NULL_TREE;
-   tree usings;
-   timevar_push (TV_NAME_LOOKUP);
-   /* Look through namespace aliases.  */
-   scope = ORIGINAL_NAMESPACE (scope);
-   while (scope && result->value != error_mark_node)
-     {
-       cxx_binding *binding =
-         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);
-       if (!result->value && !result->type)
- 	/* Consider using directives.  */
- 	for (usings = DECL_NAMESPACE_USING (scope); usings;
- 	     usings = TREE_CHAIN (usings))
- 	  /* If this was a real directive, and we have not seen it.  */
- 	  if (!TREE_INDIRECT_USING (usings)
- 	      && !purpose_member (TREE_PURPOSE (usings), seen))
- 	    todo = tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
-       if (todo)
- 	{
- 	  scope = TREE_PURPOSE (todo);
- 	  todo = TREE_CHAIN (todo);
- 	}
-       else
- 	scope = NULL_TREE; /* If there never was a todo list.  */
-     }
-   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
- }
- 
- /* [namespace.memdef]/2 */
- 
- /* Set the context of a declaration to scope. Complain if we are not
-    outside scope.  */
- 
- void
- set_decl_namespace (tree decl, tree scope, bool friendp)
- {
-   tree old;
-   
-   /* Get rid of namespace aliases.  */
-   scope = ORIGINAL_NAMESPACE (scope);
-   
-   /* It is ok for friends to be qualified in parallel space.  */
-   if (!friendp && !is_ancestor (current_namespace, scope))
-     error ("declaration of `%D' not in a namespace surrounding `%D'",
- 	      decl, scope);
-   DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
-   if (scope != current_namespace)
-     {
-       /* See whether this has been declared in the namespace.  */
-       old = namespace_binding (DECL_NAME (decl), scope);
-       if (!old)
- 	/* No old declaration at all.  */
- 	goto complain;
-       /* A template can be explicitly specialized in any namespace.  */
-       if (processing_explicit_instantiation)
- 	return;
-       if (!is_overloaded_fn (decl))
- 	/* Don't compare non-function decls with decls_match here,
- 	   since it can't check for the correct constness at this
- 	   point. pushdecl will find those errors later.  */
- 	return;
-       /* Since decl is a function, old should contain a function decl.  */
-       if (!is_overloaded_fn (old))
- 	goto complain;
-       if (processing_template_decl || processing_specialization)
- 	/* We have not yet called push_template_decl to turn a
- 	   FUNCTION_DECL into a TEMPLATE_DECL, so the declarations
- 	   won't match.  But, we'll check later, when we construct the
- 	   template.  */
- 	return;
-       if (is_overloaded_fn (old))
- 	{
- 	  for (; old; old = OVL_NEXT (old))
- 	    if (decls_match (decl, OVL_CURRENT (old)))
- 	      return;
- 	}
-       else
- 	if (decls_match (decl, old))
- 	  return;
-     }
-   else
-     return;
-  complain:
-   error ("`%D' should have been declared inside `%D'",
- 	    decl, scope);
- } 
- 
- /* Compute the namespace where a declaration is defined.  */
- 
- static tree
- decl_namespace (tree decl)
- {
-   timevar_push (TV_NAME_LOOKUP);
-   if (TYPE_P (decl))
-     decl = TYPE_STUB_DECL (decl);
-   while (DECL_CONTEXT (decl))
-     {
-       decl = DECL_CONTEXT (decl);
-       if (TREE_CODE (decl) == NAMESPACE_DECL)
- 	POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
-       if (TYPE_P (decl))
- 	decl = TYPE_STUB_DECL (decl);
-       my_friendly_assert (DECL_P (decl), 390);
-     }
- 
-   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, global_namespace);
- }
- 
- /* Return the namespace where the current declaration is declared.  */
- 
- tree
- current_decl_namespace (void)
- {
-   tree result;
-   /* If we have been pushed into a different namespace, use it.  */
-   if (decl_namespace_list)
-     return TREE_PURPOSE (decl_namespace_list);
- 
-   if (current_class_type)
-     result = decl_namespace (TYPE_STUB_DECL (current_class_type));
-   else if (current_function_decl)
-     result = decl_namespace (current_function_decl);
-   else 
-     result = current_namespace;
-   return result;
- }
- 
- /* Temporarily set the namespace for the current declaration.  */
- 
- void
- push_decl_namespace (tree decl)
- {
-   if (TREE_CODE (decl) != NAMESPACE_DECL)
-     decl = decl_namespace (decl);
-   decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
-                                    NULL_TREE, decl_namespace_list);
- }
- 
- void
- pop_decl_namespace (void)
- {
-   decl_namespace_list = TREE_CHAIN (decl_namespace_list);
- }
- 
- /* Enter a class or namespace scope.  */
- 
- void
- push_scope (tree t)
- {
-   if (TREE_CODE (t) == NAMESPACE_DECL)
-     push_decl_namespace (t);
-   else if CLASS_TYPE_P (t)
-     push_nested_class (t);
- }
- 
- /* Leave scope pushed by push_scope.  */
- 
- void
- pop_scope (tree t)
- {
-   if (TREE_CODE (t) == NAMESPACE_DECL)
-     pop_decl_namespace ();
-   else if CLASS_TYPE_P (t)
-     pop_nested_class ();
- }
- 
- /* [basic.lookup.koenig] */
- /* A nonzero return value in the functions below indicates an error.  */
- 
- struct arg_lookup
- {
-   tree name;
-   tree namespaces;
-   tree classes;
-   tree functions;
- };
- 
- static bool arg_assoc (struct arg_lookup*, tree);
- static bool arg_assoc_args (struct arg_lookup*, tree);
- static bool arg_assoc_type (struct arg_lookup*, tree);
- static bool add_function (struct arg_lookup *, tree);
- static bool arg_assoc_namespace (struct arg_lookup *, tree);
- static bool arg_assoc_class (struct arg_lookup *, tree);
- static bool arg_assoc_template_arg (struct arg_lookup*, tree);
- 
- /* Add a function to the lookup structure.
-    Returns true on error.  */
- 
- static bool
- add_function (struct arg_lookup *k, tree fn)
- {
-   /* We used to check here to see if the function was already in the list,
-      but that's O(n^2), which is just too expensive for function lookup.
-      Now we deal with the occasional duplicate in joust.  In doing this, we
-      assume that the number of duplicates will be small compared to the
-      total number of functions being compared, which should usually be the
-      case.  */
- 
-   /* We must find only functions, or exactly one non-function.  */
-   if (!k->functions) 
-     k->functions = fn;
-   else if (fn == k->functions)
-     ;
-   else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn))
-     k->functions = build_overload (fn, k->functions);
-   else
-     {
-       tree f1 = OVL_CURRENT (k->functions);
-       tree f2 = fn;
-       if (is_overloaded_fn (f1))
- 	{
- 	  fn = f1; f1 = f2; f2 = fn;
- 	}
-       cp_error_at ("`%D' is not a function,", f1);
-       cp_error_at ("  conflict with `%D'", f2);
-       error ("  in call to `%D'", k->name);
-       return true;
-     }
- 
-   return false;
- }
- 
- /* Add functions of a namespace to the lookup structure.
-    Returns true on error.  */
- 
- static bool
- arg_assoc_namespace (struct arg_lookup *k, tree scope)
- {
-   tree value;
- 
-   if (purpose_member (scope, k->namespaces))
-     return 0;
-   k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces);
-   
-   value = namespace_binding (k->name, scope);
-   if (!value)
-     return false;
- 
-   for (; value; value = OVL_NEXT (value))
-     if (add_function (k, OVL_CURRENT (value)))
-       return true;
    
-   return false;
- }
- 
- /* Adds everything associated with a template argument to the lookup
-    structure.  Returns true on error.  */
- 
- static bool
- arg_assoc_template_arg (struct arg_lookup *k, tree arg)
- {
-   /* [basic.lookup.koenig]
- 
-      If T is a template-id, its associated namespaces and classes are
-      ... the namespaces and classes associated with the types of the
-      template arguments provided for template type parameters
-      (excluding template template parameters); the namespaces in which
-      any template template arguments are defined; and the classes in
-      which any member templates used as template template arguments
-      are defined.  [Note: non-type template arguments do not
-      contribute to the set of associated namespaces.  ]  */
- 
-   /* Consider first template template arguments.  */
-   if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
-       || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)
-     return false;
-   else if (TREE_CODE (arg) == TEMPLATE_DECL)
-     {
-       tree ctx = CP_DECL_CONTEXT (arg);
- 
-       /* It's not a member template.  */
-       if (TREE_CODE (ctx) == NAMESPACE_DECL)
-         return arg_assoc_namespace (k, ctx);
-       /* Otherwise, it must be member template.  */
-       else 
-         return arg_assoc_class (k, ctx);
-     }
-   /* It's not a template template argument, but it is a type template
-      argument.  */
-   else if (TYPE_P (arg))
-     return arg_assoc_type (k, arg);
-   /* It's a non-type template argument.  */
-   else
-     return false;
- }
- 
- /* Adds everything associated with class to the lookup structure.
-    Returns true on error.  */
- 
- static bool
- arg_assoc_class (struct arg_lookup *k, tree type)
- {
-   tree list, friends, context;
-   int i;
-   
-   /* Backend build structures, such as __builtin_va_list, aren't
-      affected by all this.  */
-   if (!CLASS_TYPE_P (type))
-     return false;
- 
-   if (purpose_member (type, k->classes))
-     return false;
-   k->classes = tree_cons (type, NULL_TREE, k->classes);
-   
-   context = decl_namespace (TYPE_MAIN_DECL (type));
-   if (arg_assoc_namespace (k, context))
-     return true;
-   
-   /* Process baseclasses.  */
-   for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); i++)
-     if (arg_assoc_class (k, TYPE_BINFO_BASETYPE (type, i)))
-       return true;
-   
-   /* Process friends.  */
-   for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list; 
-        list = TREE_CHAIN (list))
-     if (k->name == FRIEND_NAME (list))
-       for (friends = FRIEND_DECLS (list); friends; 
- 	   friends = TREE_CHAIN (friends))
- 	/* Only interested in global functions with potentially hidden
-            (i.e. unqualified) declarations.  */
- 	if (CP_DECL_CONTEXT (TREE_VALUE (friends)) == context)
- 	  if (add_function (k, TREE_VALUE (friends)))
- 	    return true;
- 
-   /* Process template arguments.  */
-   if (CLASSTYPE_TEMPLATE_INFO (type))
-     {
-       list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
-       for (i = 0; i < TREE_VEC_LENGTH (list); ++i) 
-         arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
-     }
- 
-   return false;
- }
- 
- /* Adds everything associated with a given type.
-    Returns 1 on error.  */
- 
- static bool
- arg_assoc_type (struct arg_lookup *k, tree type)
- {
-   /* As we do not get the type of non-type dependent expressions
-      right, we can end up with such things without a type.  */
-   if (!type)
-     return false;
- 
-   if (TYPE_PTRMEM_P (type))
-     {
-       /* Pointer to member: associate class type and value type.  */
-       if (arg_assoc_type (k, TYPE_PTRMEM_CLASS_TYPE (type)))
- 	return true;
-       return arg_assoc_type (k, TYPE_PTRMEM_POINTED_TO_TYPE (type));
-     }
-   else switch (TREE_CODE (type))
-     {
-     case ERROR_MARK:
-       return false;
-     case VOID_TYPE:
-     case INTEGER_TYPE:
-     case REAL_TYPE:
-     case COMPLEX_TYPE:
-     case VECTOR_TYPE:
-     case CHAR_TYPE:
-     case BOOLEAN_TYPE:
-       return false;
-     case RECORD_TYPE:
-       if (TYPE_PTRMEMFUNC_P (type))
- 	return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
-       return arg_assoc_class (k, type);
-     case POINTER_TYPE:
-     case REFERENCE_TYPE:
-     case ARRAY_TYPE:
-       return arg_assoc_type (k, TREE_TYPE (type));
-     case UNION_TYPE:
-     case ENUMERAL_TYPE:
-       return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type)));
-     case METHOD_TYPE:
-       /* The basetype is referenced in the first arg type, so just
- 	 fall through.  */
-     case FUNCTION_TYPE:
-       /* Associate the parameter types.  */
-       if (arg_assoc_args (k, TYPE_ARG_TYPES (type)))
- 	return true;
-       /* Associate the return type.  */
-       return arg_assoc_type (k, TREE_TYPE (type));
-     case TEMPLATE_TYPE_PARM:
-     case BOUND_TEMPLATE_TEMPLATE_PARM:
-       return false;
-     case TYPENAME_TYPE:
-       return false;
-     case LANG_TYPE:
-       if (type == unknown_type_node)
- 	return false;
-       /* else fall through */
-     default:
-       abort ();
-     }
-   return false;
- }
- 
- /* Adds everything associated with arguments.  Returns true on error.  */
- 
- static bool
- arg_assoc_args (struct arg_lookup *k, tree args)
- {
-   for (; args; args = TREE_CHAIN (args))
-     if (arg_assoc (k, TREE_VALUE (args)))
-       return true;
-   return false;
- }
- 
- /* Adds everything associated with a given tree_node.  Returns 1 on error.  */
- 
- static bool
- arg_assoc (struct arg_lookup *k, tree n)
- {
-   if (n == error_mark_node)
-     return false;
- 
-   if (TYPE_P (n))
-     return arg_assoc_type (k, n);
- 
-   if (! type_unknown_p (n))
-     return arg_assoc_type (k, TREE_TYPE (n));
- 
-   if (TREE_CODE (n) == ADDR_EXPR)
-     n = TREE_OPERAND (n, 0);
-   if (TREE_CODE (n) == COMPONENT_REF)
-     n = TREE_OPERAND (n, 1);
-   if (TREE_CODE (n) == OFFSET_REF)
-     n = TREE_OPERAND (n, 1);
-   while (TREE_CODE (n) == TREE_LIST)
-     n = TREE_VALUE (n);
-   if (TREE_CODE (n) == BASELINK)
-     n = BASELINK_FUNCTIONS (n);
- 
-   if (TREE_CODE (n) == FUNCTION_DECL)
-     return arg_assoc_type (k, TREE_TYPE (n));
-   if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
-     {
-       /* [basic.lookup.koenig]
- 
- 	 If T is a template-id, its associated namespaces and classes
- 	 are the namespace in which the template is defined; for
- 	 member templates, the member template's class...  */
-       tree template = TREE_OPERAND (n, 0);
-       tree args = TREE_OPERAND (n, 1);
-       tree ctx;
-       int ix;
- 
-       if (TREE_CODE (template) == COMPONENT_REF)
-         template = TREE_OPERAND (template, 1);
-       
-       /* First, the template.  There may actually be more than one if
- 	 this is an overloaded function template.  But, in that case,
- 	 we only need the first; all the functions will be in the same
- 	 namespace.  */
-       template = OVL_CURRENT (template);
- 
-       ctx = CP_DECL_CONTEXT (template);
-        
-       if (TREE_CODE (ctx) == NAMESPACE_DECL)
- 	{
- 	  if (arg_assoc_namespace (k, ctx) == 1)
- 	    return true;
- 	}
-       /* It must be a member template.  */
-       else if (arg_assoc_class (k, ctx) == 1)
- 	return true;
- 
-       /* Now the arguments.  */
-       for (ix = TREE_VEC_LENGTH (args); ix--;)
- 	if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
- 	  return true;
-     }
-   else
-     {
-       my_friendly_assert (TREE_CODE (n) == OVERLOAD, 980715);
-       
-       for (; n; n = OVL_CHAIN (n))
- 	if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n))))
- 	  return true;
-     }
- 
-   return false;
- }
- 
- /* Performs Koenig lookup depending on arguments, where fns
-    are the functions found in normal lookup.  */
- 
- tree
- lookup_arg_dependent (tree name, tree fns, tree args)
- {
-   struct arg_lookup k;
-   tree fn = NULL_TREE;
- 
-   timevar_push (TV_NAME_LOOKUP);
-   k.name = name;
-   k.functions = fns;
-   k.classes = NULL_TREE;
- 
-   /* Note that we've already looked at some namespaces during normal
-      unqualified lookup, unless we found a decl in function scope.  */
-   if (fns)
-     fn = OVL_CURRENT (fns);
-   if (fn && TREE_CODE (fn) == FUNCTION_DECL && DECL_LOCAL_FUNCTION_P (fn))
-     k.namespaces = NULL_TREE;
-   else
-     unqualified_namespace_lookup (name, 0, &k.namespaces);
- 
-   arg_assoc_args (&k, args);
-   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, k.functions);
- }
- 
- /* Process a namespace-alias declaration.  */
- 
- void
- do_namespace_alias (tree alias, tree namespace)
- {
-   if (TREE_CODE (namespace) != NAMESPACE_DECL)
-     {
-       /* The parser did not find it, so it's not there.  */
-       error ("unknown namespace `%D'", namespace);
-       return;
-     }
- 
-   namespace = ORIGINAL_NAMESPACE (namespace);
- 
-   /* Build the alias.  */
-   alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);     
-   DECL_NAMESPACE_ALIAS (alias) = namespace;
-   DECL_EXTERNAL (alias) = 1;
-   pushdecl (alias);
- }
- 
- /* Check a non-member using-declaration. Return the name and scope
-    being used, and the USING_DECL, or NULL_TREE on failure.  */
- 
- static tree
- validate_nonmember_using_decl (tree decl, tree *scope, tree *name)
- {
-   *scope = global_namespace;
-   *name = NULL_TREE;
- 
-   if (TREE_CODE (decl) == TEMPLATE_ID_EXPR)
-     {
-       *name = TREE_OPERAND (decl, 0);
-       /* 7.3.3/5
- 	   A using-declaration shall not name a template-id.  */
-       error ("a using-declaration cannot specify a template-id.  Try `using %D'", *name);
-       return NULL_TREE;
-     }
- 
-   if (TREE_CODE (decl) == NAMESPACE_DECL)
-     {
-       error ("namespace `%D' not allowed in using-declaration", decl);
-       return NULL_TREE;
-     }
- 
-   if (TREE_CODE (decl) == SCOPE_REF)
-     {
-       /* It's a nested name with template parameter dependent scope.
- 	 This can only be using-declaration for class member.  */
-       error ("`%T' is not a namespace", TREE_OPERAND (decl, 0));
-       return NULL_TREE;
-     }
- 
-   if (is_overloaded_fn (decl))
-     decl = get_first_fn (decl);
- 
-   my_friendly_assert (DECL_P (decl), 20020908);
- 
-   if (TREE_CODE (decl) == CONST_DECL)
-     /* Enumeration constants to not have DECL_CONTEXT set.  */
-     *scope = TYPE_CONTEXT (TREE_TYPE (decl));
-   else
-     *scope = DECL_CONTEXT (decl);
-   if (!*scope)
-     *scope = global_namespace;
- 
-   /* [namespace.udecl]
-        A using-declaration for a class member shall be a
-        member-declaration.  */
-   if (TYPE_P (*scope))
-     {
-       error ("`%T' is not a namespace", *scope);
-       return NULL_TREE;
-     }
-   *name = DECL_NAME (decl);
-   /* Make a USING_DECL.  */
-   return push_using_decl (*scope, *name);
- }
- 
- /* Process local and global using-declarations.  */
- 
- static void
- do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
-                          tree *newval, tree *newtype)
- {
-   cxx_binding decls;
- 
-   *newval = *newtype = NULL_TREE;
-   cxx_binding_clear (&decls);
-   if (!qualified_lookup_using_namespace (name, scope, &decls, 0))
-     /* Lookup error */
-     return;
- 
-   if (!decls.value && !decls.type)
-     {
-       error ("`%D' not declared", name);
-       return;
-     }
- 
-   /* Check for using functions.  */
-   if (decls.value && is_overloaded_fn (decls.value))
-     {
-       tree tmp, tmp1;
- 
-       if (oldval && !is_overloaded_fn (oldval))
- 	{
- 	  if (!DECL_IMPLICIT_TYPEDEF_P (oldval))
- 	    error ("`%D' is already declared in this scope", name);
- 	  oldval = NULL_TREE;
- 	}
- 
-       *newval = oldval;
-       for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
- 	{
- 	  tree new_fn = OVL_CURRENT (tmp);
- 
- 	  /* [namespace.udecl]
- 
- 	     If a function declaration in namespace scope or block
- 	     scope has the same name and the same parameter types as a
- 	     function introduced by a using declaration the program is
- 	     ill-formed.  */
- 	  for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
- 	    {
- 	      tree old_fn = OVL_CURRENT (tmp1);
- 
-               if (new_fn == old_fn)
-                 /* The function already exists in the current namespace.  */
-                 break;
- 	      else if (OVL_USED (tmp1))
- 	        continue; /* this is a using decl */
- 	      else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
- 		  		  TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
- 		{
- 	          /* There was already a non-using declaration in
- 		     this scope with the same parameter types. If both
- 	             are the same extern "C" functions, that's ok.  */
-                   if (decls_match (new_fn, old_fn))
- 		    {
- 		      /* If the OLD_FN was a builtin, there is now a
- 			 real declaration.  */
- 		      if (DECL_ANTICIPATED (old_fn))
- 			DECL_ANTICIPATED (old_fn) = 0;
- 		      break;
- 		    }
- 		  else if (!DECL_ANTICIPATED (old_fn))
- 		    {
- 		      /* If the OLD_FN was really declared, the
- 			 declarations don't match.  */
- 		      error ("`%D' is already declared in this scope", name);
- 		      break;
- 		    }
- 
- 		  /* If the OLD_FN was not really there, just ignore
- 		     it and keep going.  */
- 		}
- 	    }
- 
- 	  /* If we broke out of the loop, there's no reason to add
- 	     this function to the using declarations for this
- 	     scope.  */
- 	  if (tmp1)
- 	    continue;
- 	    
- 	  *newval = build_overload (OVL_CURRENT (tmp), *newval);
- 	  if (TREE_CODE (*newval) != OVERLOAD)
- 	    *newval = ovl_cons (*newval, NULL_TREE);
- 	  OVL_USED (*newval) = 1;
- 	}
-     }
-   else 
-     {
-       *newval = decls.value;
-       if (oldval && !decls_match (*newval, oldval))
- 	error ("`%D' is already declared in this scope", name);
-     }
- 
-   *newtype = decls.type;
-   if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
-     {
-       error ("using declaration `%D' introduced ambiguous type `%T'",
- 		name, oldtype);
-       return;
-     }
- }
- 
- /* Process a using-declaration not appearing in class or local scope.  */
- 
- void
- do_toplevel_using_decl (tree decl)
- {
-   tree scope, name;
-   tree oldval, oldtype, newval, newtype;
-   cxx_binding *binding;
- 
-   decl = validate_nonmember_using_decl (decl, &scope, &name);
-   if (decl == NULL_TREE)
-     return;
-   
-   binding = binding_for_name (NAMESPACE_LEVEL (current_namespace), name);
- 
-   oldval = binding->value;
-   oldtype = binding->type;
- 
-   do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
- 
-   /* Copy declarations found.  */
-   if (newval)
-     binding->value = newval;
-   if (newtype)
-     binding->type = newtype;
-   return;
- }
- 
- /* Process a using-declaration at function scope.  */
- 
- void
- do_local_using_decl (tree decl)
- {
-   tree scope, name;
-   tree oldval, oldtype, newval, newtype;
- 
-   decl = validate_nonmember_using_decl (decl, &scope, &name);
-   if (decl == NULL_TREE)
-     return;
- 
-   if (building_stmt_tree ()
-       && at_function_scope_p ())
-     add_decl_stmt (decl);
- 
-   oldval = lookup_name_current_level (name);
-   oldtype = lookup_type_current_level (name);
- 
-   do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
- 
-   if (newval)
-     {
-       if (is_overloaded_fn (newval))
- 	{
- 	  tree fn, term;
- 
- 	  /* We only need to push declarations for those functions
- 	     that were not already bound in the current level.
- 	     The old value might be NULL_TREE, it might be a single
- 	     function, or an OVERLOAD.  */
- 	  if (oldval && TREE_CODE (oldval) == OVERLOAD)
- 	    term = OVL_FUNCTION (oldval);
- 	  else
- 	    term = oldval;
- 	  for (fn = newval; fn && OVL_CURRENT (fn) != term; 
- 	       fn = OVL_NEXT (fn))
- 	    push_overloaded_decl (OVL_CURRENT (fn), 
- 				  PUSH_LOCAL | PUSH_USING);
- 	}
-       else
- 	push_local_binding (name, newval, PUSH_USING);
-     }
-   if (newtype)
-     set_identifier_type_value (name, newtype);
- }
- 
- tree
- do_class_using_decl (tree decl)
- {
-   tree name, value, scope, type;
-   
-   if (TREE_CODE (decl) != SCOPE_REF
-       || !TREE_OPERAND (decl, 0)
-       || !TYPE_P (TREE_OPERAND (decl, 0)))
-     {
-       error ("using-declaration for non-member at class scope");
-       return NULL_TREE;
-     }
-   scope = TREE_OPERAND (decl, 0);
-   name = TREE_OPERAND (decl, 1);
-   if (TREE_CODE (name) == BIT_NOT_EXPR)
-     {
-       error ("using-declaration cannot name destructor");
-       return NULL_TREE;
-     }
-   if (TREE_CODE (name) == TYPE_DECL)
-     name = DECL_NAME (name);
-   else if (TREE_CODE (name) == TEMPLATE_DECL)
-      name = DECL_NAME (name);
-   else if (BASELINK_P (name))
-     {
-       tree fns = BASELINK_FUNCTIONS (name);
-       name = DECL_NAME (get_first_fn (fns));
-     }
- 
-   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
- 
-   /* Dependent using decls have a NULL type, non-dependent ones have a
-      void type.  */
-   type = dependent_type_p (scope) ? NULL_TREE : void_type_node;
-   value = build_lang_decl (USING_DECL, name, type);
-   DECL_INITIAL (value) = scope;
-   return value;
- }
- 
- /* Process a using-directive.  */
- 
- void
- do_using_directive (tree namespace)
- {
-   if (building_stmt_tree ())
-     add_stmt (build_stmt (USING_STMT, namespace));
-   
-   /* using namespace A::B::C; */
-   if (TREE_CODE (namespace) == SCOPE_REF)
-       namespace = TREE_OPERAND (namespace, 1);
-   if (TREE_CODE (namespace) == IDENTIFIER_NODE)
-     {
-       /* Lookup in lexer did not find a namespace.  */
-       if (!processing_template_decl)
- 	error ("namespace `%T' undeclared", namespace);
-       return;
-     }
-   if (TREE_CODE (namespace) != NAMESPACE_DECL)
-     {
-       if (!processing_template_decl)
- 	error ("`%T' is not a namespace", namespace);
-       return;
-     }
-   namespace = ORIGINAL_NAMESPACE (namespace);
-   if (!toplevel_bindings_p ())
-     push_using_directive (namespace);
-   else
-     /* direct usage */
-     add_using_namespace (current_namespace, namespace, 0);
- }
  
  void
  check_default_args (tree x)
--- 2952,2958 ----
Index: name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.14
diff -p -r1.14 name-lookup.c
*** name-lookup.c	13 Oct 2003 10:26:36 -0000	1.14
--- name-lookup.c	13 Oct 2003 12:56:10 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 32,37 ****
--- 32,42 ----
  
  static cxx_scope *innermost_nonclass_level (void);
  static tree select_decl (cxx_binding *, int);
+ static cxx_binding *binding_for_name (cxx_scope *, tree);
+ 
+ /* The :: namespace.  */
+ 
+ tree global_namespace;
  
  
  /* Compute the chain index of a binding_entry given the HASH value of its
*************** binding_table_foreach (binding_table tab
*** 300,305 ****
--- 305,313 ----
  
  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 *
*************** set_identifier_type_value (tree id, tree
*** 1118,1123 ****
--- 1126,1182 ----
    set_identifier_type_value_with_scope (id, decl, current_binding_level);
  }
  
+ /* Return the name for the constructor (or destructor) for the
+    specified class TYPE.  When given a template, this routine doesn't
+    lose the specialization.  */
+ 
+ tree
+ constructor_name_full (tree type)
+ {
+   type = TYPE_MAIN_VARIANT (type);
+   if (CLASS_TYPE_P (type) && TYPE_WAS_ANONYMOUS (type) 
+       && TYPE_HAS_CONSTRUCTOR (type))
+     return DECL_NAME (OVL_CURRENT (CLASSTYPE_CONSTRUCTORS (type)));
+   else
+     return TYPE_IDENTIFIER (type);
+ }
+ 
+ /* Return the name for the constructor (or destructor) for the
+    specified class.  When given a template, return the plain
+    unspecialized name.  */
+ 
+ tree
+ constructor_name (tree type)
+ {
+   tree name;
+   name = constructor_name_full (type);
+   if (IDENTIFIER_TEMPLATE (name))
+     name = IDENTIFIER_TEMPLATE (name);
+   return name;
+ }
+ 
+ /* Returns TRUE if NAME is the name for the constructor for TYPE.  */
+ 
+ bool
+ constructor_name_p (tree name, tree type)
+ {
+   tree ctor_name;
+ 
+   if (!name)
+     return false;
+   
+   if (TREE_CODE (name) != IDENTIFIER_NODE)
+     return false;
+   
+   ctor_name = constructor_name_full (type);
+   if (name == ctor_name)
+     return true;
+   if (IDENTIFIER_TEMPLATE (ctor_name)
+       && name == IDENTIFIER_TEMPLATE (ctor_name))
+     return true;
+   return false;
+ }
+ 
  /* Return (from the stack of) the BINDING, if any, establihsed at SCOPE.  */ 
  
  static inline cxx_binding *
*************** find_binding (cxx_scope *scope, cxx_bind
*** 1134,1140 ****
  
  /* Return the binding for NAME in SCOPE, if any.  Otherwise, return NULL.  */
  
! cxx_binding *
  cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)
  {
    cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
--- 1193,1199 ----
  
  /* Return the binding for NAME in SCOPE, if any.  Otherwise, return NULL.  */
  
! static inline cxx_binding *
  cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)
  {
    cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
*************** cxx_scope_find_binding_for_name (cxx_sco
*** 1151,1157 ****
  /* Always returns a binding for name in scope.  If no binding is
     found, make a new one.  */
  
! cxx_binding *
  binding_for_name (cxx_scope *scope, tree name)
  {
    cxx_binding *result;
--- 1210,1216 ----
  /* Always returns a binding for name in scope.  If no binding is
     found, make a new one.  */
  
! static cxx_binding *
  binding_for_name (cxx_scope *scope, tree name)
  {
    cxx_binding *result;
*************** pushdecl_with_scope (tree x, cxx_scope *
*** 1198,1203 ****
--- 1257,1474 ----
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
  }
  
+ /* Check a non-member using-declaration. Return the name and scope
+    being used, and the USING_DECL, or NULL_TREE on failure.  */
+ 
+ static tree
+ validate_nonmember_using_decl (tree decl, tree *scope, tree *name)
+ {
+   *scope = global_namespace;
+   *name = NULL_TREE;
+ 
+   if (TREE_CODE (decl) == TEMPLATE_ID_EXPR)
+     {
+       *name = TREE_OPERAND (decl, 0);
+       /* 7.3.3/5
+ 	   A using-declaration shall not name a template-id.  */
+       error ("a using-declaration cannot specify a template-id.  Try `using %D'", *name);
+       return NULL_TREE;
+     }
+ 
+   if (TREE_CODE (decl) == NAMESPACE_DECL)
+     {
+       error ("namespace `%D' not allowed in using-declaration", decl);
+       return NULL_TREE;
+     }
+ 
+   if (TREE_CODE (decl) == SCOPE_REF)
+     {
+       /* It's a nested name with template parameter dependent scope.
+ 	 This can only be using-declaration for class member.  */
+       error ("`%T' is not a namespace", TREE_OPERAND (decl, 0));
+       return NULL_TREE;
+     }
+ 
+   if (is_overloaded_fn (decl))
+     decl = get_first_fn (decl);
+ 
+   my_friendly_assert (DECL_P (decl), 20020908);
+ 
+   if (TREE_CODE (decl) == CONST_DECL)
+     /* Enumeration constants to not have DECL_CONTEXT set.  */
+     *scope = TYPE_CONTEXT (TREE_TYPE (decl));
+   else
+     *scope = DECL_CONTEXT (decl);
+   if (!*scope)
+     *scope = global_namespace;
+ 
+   /* [namespace.udecl]
+        A using-declaration for a class member shall be a
+        member-declaration.  */
+   if (TYPE_P (*scope))
+     {
+       error ("`%T' is not a namespace", *scope);
+       return NULL_TREE;
+     }
+   *name = DECL_NAME (decl);
+   /* Make a USING_DECL.  */
+   return push_using_decl (*scope, *name);
+ }
+ 
+ /* Process local and global using-declarations.  */
+ 
+ static void
+ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
+                          tree *newval, tree *newtype)
+ {
+   cxx_binding decls;
+ 
+   *newval = *newtype = NULL_TREE;
+   cxx_binding_clear (&decls);
+   if (!qualified_lookup_using_namespace (name, scope, &decls, 0))
+     /* Lookup error */
+     return;
+ 
+   if (!decls.value && !decls.type)
+     {
+       error ("`%D' not declared", name);
+       return;
+     }
+ 
+   /* Check for using functions.  */
+   if (decls.value && is_overloaded_fn (decls.value))
+     {
+       tree tmp, tmp1;
+ 
+       if (oldval && !is_overloaded_fn (oldval))
+ 	{
+ 	  if (!DECL_IMPLICIT_TYPEDEF_P (oldval))
+ 	    error ("`%D' is already declared in this scope", name);
+ 	  oldval = NULL_TREE;
+ 	}
+ 
+       *newval = oldval;
+       for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
+ 	{
+ 	  tree new_fn = OVL_CURRENT (tmp);
+ 
+ 	  /* [namespace.udecl]
+ 
+ 	     If a function declaration in namespace scope or block
+ 	     scope has the same name and the same parameter types as a
+ 	     function introduced by a using declaration the program is
+ 	     ill-formed.  */
+ 	  for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
+ 	    {
+ 	      tree old_fn = OVL_CURRENT (tmp1);
+ 
+               if (new_fn == old_fn)
+                 /* The function already exists in the current namespace.  */
+                 break;
+ 	      else if (OVL_USED (tmp1))
+ 	        continue; /* this is a using decl */
+ 	      else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
+ 		  		  TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+ 		{
+ 	          /* There was already a non-using declaration in
+ 		     this scope with the same parameter types. If both
+ 	             are the same extern "C" functions, that's ok.  */
+                   if (decls_match (new_fn, old_fn))
+ 		    {
+ 		      /* If the OLD_FN was a builtin, there is now a
+ 			 real declaration.  */
+ 		      if (DECL_ANTICIPATED (old_fn))
+ 			DECL_ANTICIPATED (old_fn) = 0;
+ 		      break;
+ 		    }
+ 		  else if (!DECL_ANTICIPATED (old_fn))
+ 		    {
+ 		      /* If the OLD_FN was really declared, the
+ 			 declarations don't match.  */
+ 		      error ("`%D' is already declared in this scope", name);
+ 		      break;
+ 		    }
+ 
+ 		  /* If the OLD_FN was not really there, just ignore
+ 		     it and keep going.  */
+ 		}
+ 	    }
+ 
+ 	  /* If we broke out of the loop, there's no reason to add
+ 	     this function to the using declarations for this
+ 	     scope.  */
+ 	  if (tmp1)
+ 	    continue;
+ 	    
+ 	  *newval = build_overload (OVL_CURRENT (tmp), *newval);
+ 	  if (TREE_CODE (*newval) != OVERLOAD)
+ 	    *newval = ovl_cons (*newval, NULL_TREE);
+ 	  OVL_USED (*newval) = 1;
+ 	}
+     }
+   else 
+     {
+       *newval = decls.value;
+       if (oldval && !decls_match (*newval, oldval))
+ 	error ("`%D' is already declared in this scope", name);
+     }
+ 
+   *newtype = decls.type;
+   if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
+     {
+       error ("using declaration `%D' introduced ambiguous type `%T'",
+ 		name, oldtype);
+       return;
+     }
+ }
+ 
+ /* Process a using-declaration at function scope.  */
+ 
+ void
+ do_local_using_decl (tree decl)
+ {
+   tree scope, name;
+   tree oldval, oldtype, newval, newtype;
+ 
+   decl = validate_nonmember_using_decl (decl, &scope, &name);
+   if (decl == NULL_TREE)
+     return;
+ 
+   if (building_stmt_tree ()
+       && at_function_scope_p ())
+     add_decl_stmt (decl);
+ 
+   oldval = lookup_name_current_level (name);
+   oldtype = lookup_type_current_level (name);
+ 
+   do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
+ 
+   if (newval)
+     {
+       if (is_overloaded_fn (newval))
+ 	{
+ 	  tree fn, term;
+ 
+ 	  /* We only need to push declarations for those functions
+ 	     that were not already bound in the current level.
+ 	     The old value might be NULL_TREE, it might be a single
+ 	     function, or an OVERLOAD.  */
+ 	  if (oldval && TREE_CODE (oldval) == OVERLOAD)
+ 	    term = OVL_FUNCTION (oldval);
+ 	  else
+ 	    term = oldval;
+ 	  for (fn = newval; fn && OVL_CURRENT (fn) != term; 
+ 	       fn = OVL_NEXT (fn))
+ 	    push_overloaded_decl (OVL_CURRENT (fn), 
+ 				  PUSH_LOCAL | PUSH_USING);
+ 	}
+       else
+ 	push_local_binding (name, newval, PUSH_USING);
+     }
+   if (newtype)
+     set_identifier_type_value (name, newtype);
+ }
+ 
  /* Return the type that should be used when TYPE's name is preceded
     by a tag such as 'struct' or 'union', or null if the name cannot
     be used in this way.
*************** lookup_tag_reverse (tree type, tree name
*** 1378,1383 ****
--- 1649,1708 ----
      }
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
  }
+ 
+ /* Returns true if ROOT (a namespace, class, or function) encloses
+    CHILD.  CHILD may be either a class type or a namespace.  */
+ 
+ bool
+ is_ancestor (tree root, tree child)
+ {
+   my_friendly_assert ((TREE_CODE (root) == NAMESPACE_DECL
+ 		       || TREE_CODE (root) == FUNCTION_DECL
+ 		       || CLASS_TYPE_P (root)), 20030307);
+   my_friendly_assert ((TREE_CODE (child) == NAMESPACE_DECL
+ 		       || CLASS_TYPE_P (child)),
+ 		      20030307);
+   
+   /* The global namespace encloses everything.  */
+   if (root == global_namespace)
+     return true;
+ 
+   while (true)
+     {
+       /* If we've run out of scopes, stop.  */
+       if (!child)
+ 	return false;
+       /* If we've reached the ROOT, it encloses CHILD.  */
+       if (root == child)
+ 	return true;
+       /* Go out one level.  */
+       if (TYPE_P (child))
+ 	child = TYPE_NAME (child);
+       child = DECL_CONTEXT (child);
+     }
+ }
+ 
+ /* Enter a class or namespace scope.  */
+ 
+ void
+ push_scope (tree t)
+ {
+   if (TREE_CODE (t) == NAMESPACE_DECL)
+     push_decl_namespace (t);
+   else if CLASS_TYPE_P (t)
+     push_nested_class (t);
+ }
+ 
+ /* Leave scope pushed by push_scope.  */
+ 
+ void
+ pop_scope (tree t)
+ {
+   if (TREE_CODE (t) == NAMESPACE_DECL)
+     pop_decl_namespace ();
+   else if CLASS_TYPE_P (t)
+     pop_nested_class ();
+ }
  
  /* Do a pushlevel for class declarations.  */
  
*************** push_class_level_binding (tree name, tre
*** 1671,1676 ****
--- 1996,2040 ----
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
  }
  
+ tree
+ do_class_using_decl (tree decl)
+ {
+   tree name, value, scope, type;
+   
+   if (TREE_CODE (decl) != SCOPE_REF
+       || !TREE_OPERAND (decl, 0)
+       || !TYPE_P (TREE_OPERAND (decl, 0)))
+     {
+       error ("using-declaration for non-member at class scope");
+       return NULL_TREE;
+     }
+   scope = TREE_OPERAND (decl, 0);
+   name = TREE_OPERAND (decl, 1);
+   if (TREE_CODE (name) == BIT_NOT_EXPR)
+     {
+       error ("using-declaration cannot name destructor");
+       return NULL_TREE;
+     }
+   if (TREE_CODE (name) == TYPE_DECL)
+     name = DECL_NAME (name);
+   else if (TREE_CODE (name) == TEMPLATE_DECL)
+      name = DECL_NAME (name);
+   else if (BASELINK_P (name))
+     {
+       tree fns = BASELINK_FUNCTIONS (name);
+       name = DECL_NAME (get_first_fn (fns));
+     }
+ 
+   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
+ 
+   /* Dependent using decls have a NULL type, non-dependent ones have a
+      void type.  */
+   type = dependent_type_p (scope) ? NULL_TREE : void_type_node;
+   value = build_lang_decl (USING_DECL, name, type);
+   DECL_INITIAL (value) = scope;
+   return value;
+ }
+ 
  void
  set_class_shadows (tree shadows)
  {
*************** set_namespace_binding (tree name, tree s
*** 1710,1715 ****
--- 2074,2176 ----
    timevar_pop (TV_NAME_LOOKUP);
  }
  
+ /* Compute the namespace where a declaration is defined.  */
+ 
+ static tree
+ decl_namespace (tree decl)
+ {
+   timevar_push (TV_NAME_LOOKUP);
+   if (TYPE_P (decl))
+     decl = TYPE_STUB_DECL (decl);
+   while (DECL_CONTEXT (decl))
+     {
+       decl = DECL_CONTEXT (decl);
+       if (TREE_CODE (decl) == NAMESPACE_DECL)
+ 	POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+       if (TYPE_P (decl))
+ 	decl = TYPE_STUB_DECL (decl);
+       my_friendly_assert (DECL_P (decl), 390);
+     }
+ 
+   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, global_namespace);
+ }
+ 
+ /* Set the context of a declaration to scope. Complain if we are not
+    outside scope.  */
+ 
+ void
+ set_decl_namespace (tree decl, tree scope, bool friendp)
+ {
+   tree old;
+   
+   /* Get rid of namespace aliases.  */
+   scope = ORIGINAL_NAMESPACE (scope);
+   
+   /* It is ok for friends to be qualified in parallel space.  */
+   if (!friendp && !is_ancestor (current_namespace, scope))
+     error ("declaration of `%D' not in a namespace surrounding `%D'",
+ 	      decl, scope);
+   DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
+   if (scope != current_namespace)
+     {
+       /* See whether this has been declared in the namespace.  */
+       old = namespace_binding (DECL_NAME (decl), scope);
+       if (!old)
+ 	/* No old declaration at all.  */
+ 	goto complain;
+       /* A template can be explicitly specialized in any namespace.  */
+       if (processing_explicit_instantiation)
+ 	return;
+       if (!is_overloaded_fn (decl))
+ 	/* Don't compare non-function decls with decls_match here,
+ 	   since it can't check for the correct constness at this
+ 	   point. pushdecl will find those errors later.  */
+ 	return;
+       /* Since decl is a function, old should contain a function decl.  */
+       if (!is_overloaded_fn (old))
+ 	goto complain;
+       if (processing_template_decl || processing_specialization)
+ 	/* We have not yet called push_template_decl to turn a
+ 	   FUNCTION_DECL into a TEMPLATE_DECL, so the declarations
+ 	   won't match.  But, we'll check later, when we construct the
+ 	   template.  */
+ 	return;
+       if (is_overloaded_fn (old))
+ 	{
+ 	  for (; old; old = OVL_NEXT (old))
+ 	    if (decls_match (decl, OVL_CURRENT (old)))
+ 	      return;
+ 	}
+       else
+ 	if (decls_match (decl, old))
+ 	  return;
+     }
+   else
+     return;
+  complain:
+   error ("`%D' should have been declared inside `%D'",
+ 	    decl, scope);
+ } 
+ 
+ /* Return the namespace where the current declaration is declared.  */
+ 
+ tree
+ current_decl_namespace (void)
+ {
+   tree result;
+   /* If we have been pushed into a different namespace, use it.  */
+   if (decl_namespace_list)
+     return TREE_PURPOSE (decl_namespace_list);
+ 
+   if (current_class_type)
+     result = decl_namespace (TYPE_STUB_DECL (current_class_type));
+   else if (current_function_decl)
+     result = decl_namespace (current_function_decl);
+   else 
+     result = current_namespace;
+   return result;
+ }
+ 
  /* Push into the scope of the NAME namespace.  If NAME is NULL_TREE, then we
     select a name that is unique to this compilation unit.  */
  
*************** pop_nested_namespace (tree ns)
*** 1819,1824 ****
--- 2280,2338 ----
    timevar_pop (TV_NAME_LOOKUP);
  }
  
+ /* Temporarily set the namespace for the current declaration.  */
+ 
+ void
+ push_decl_namespace (tree decl)
+ {
+   if (TREE_CODE (decl) != NAMESPACE_DECL)
+     decl = decl_namespace (decl);
+   decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
+                                    NULL_TREE, decl_namespace_list);
+ }
+ 
+ /* [namespace.memdef]/2 */
+ 
+ void
+ pop_decl_namespace (void)
+ {
+   decl_namespace_list = TREE_CHAIN (decl_namespace_list);
+ }
+ 
+ /* Return the namespace that is the common ancestor 
+    of two given namespaces.  */
+ 
+ tree
+ namespace_ancestor (tree ns1, tree ns2)
+ {
+   timevar_push (TV_NAME_LOOKUP);
+   if (is_ancestor (ns1, ns2))
+     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ns1);
+   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
+                           namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2));
+ }
+ 
+ /* Process a namespace-alias declaration.  */
+ 
+ void
+ do_namespace_alias (tree alias, tree namespace)
+ {
+   if (TREE_CODE (namespace) != NAMESPACE_DECL)
+     {
+       /* The parser did not find it, so it's not there.  */
+       error ("unknown namespace `%D'", namespace);
+       return;
+     }
+ 
+   namespace = ORIGINAL_NAMESPACE (namespace);
+ 
+   /* Build the alias.  */
+   alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);     
+   DECL_NAMESPACE_ALIAS (alias) = namespace;
+   DECL_EXTERNAL (alias) = 1;
+   pushdecl (alias);
+ }
+ 
  /* Like pushdecl, only it places X in the current namespace,
     if appropriate.  */
  
*************** pushdecl_namespace_level (tree x)
*** 1865,1870 ****
--- 2379,2615 ----
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  }
  
+ /* Insert USED into the using list of USER. Set INDIRECT_flag if this
+    directive is not directly from the source. Also find the common
+    ancestor and let our users know about the new namespace */
+ static void 
+ add_using_namespace (tree user, tree used, bool indirect)
+ {
+   tree t;
+   timevar_push (TV_NAME_LOOKUP);
+   /* Using oneself is a no-op.  */
+   if (user == used)
+     {
+       timevar_pop (TV_NAME_LOOKUP);
+       return;
+     }
+   my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380);
+   my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380);
+   /* Check if we already have this.  */
+   t = purpose_member (used, DECL_NAMESPACE_USING (user));
+   if (t != NULL_TREE)
+     {
+       if (!indirect)
+ 	/* Promote to direct usage.  */
+ 	TREE_INDIRECT_USING (t) = 0;
+       timevar_pop (TV_NAME_LOOKUP);
+       return;
+     }
+ 
+   /* Add used to the user's using list.  */
+   DECL_NAMESPACE_USING (user) 
+     = tree_cons (used, namespace_ancestor (user, used), 
+ 		 DECL_NAMESPACE_USING (user));
+ 
+   TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
+ 
+   /* Add user to the used's users list.  */
+   DECL_NAMESPACE_USERS (used)
+     = tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
+ 
+   /* Recursively add all namespaces used.  */
+   for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
+     /* indirect usage */
+     add_using_namespace (user, TREE_PURPOSE (t), 1);
+ 
+   /* Tell everyone using us about the new used namespaces.  */
+   for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t))
+     add_using_namespace (TREE_PURPOSE (t), used, 1);
+   timevar_pop (TV_NAME_LOOKUP);
+ }
+ 
+ /* Process a using-declaration not appearing in class or local scope.  */
+ 
+ void
+ do_toplevel_using_decl (tree decl)
+ {
+   tree scope, name;
+   tree oldval, oldtype, newval, newtype;
+   cxx_binding *binding;
+ 
+   decl = validate_nonmember_using_decl (decl, &scope, &name);
+   if (decl == NULL_TREE)
+     return;
+   
+   binding = binding_for_name (NAMESPACE_LEVEL (current_namespace), name);
+ 
+   oldval = binding->value;
+   oldtype = binding->type;
+ 
+   do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
+ 
+   /* Copy declarations found.  */
+   if (newval)
+     binding->value = newval;
+   if (newtype)
+     binding->type = newtype;
+   return;
+ }
+ 
+ /* Process a using-directive.  */
+ 
+ void
+ do_using_directive (tree namespace)
+ {
+   if (building_stmt_tree ())
+     add_stmt (build_stmt (USING_STMT, namespace));
+   
+   /* using namespace A::B::C; */
+   if (TREE_CODE (namespace) == SCOPE_REF)
+       namespace = TREE_OPERAND (namespace, 1);
+   if (TREE_CODE (namespace) == IDENTIFIER_NODE)
+     {
+       /* Lookup in lexer did not find a namespace.  */
+       if (!processing_template_decl)
+ 	error ("namespace `%T' undeclared", namespace);
+       return;
+     }
+   if (TREE_CODE (namespace) != NAMESPACE_DECL)
+     {
+       if (!processing_template_decl)
+ 	error ("`%T' is not a namespace", namespace);
+       return;
+     }
+   namespace = ORIGINAL_NAMESPACE (namespace);
+   if (!toplevel_bindings_p ())
+     push_using_directive (namespace);
+   else
+     /* direct usage */
+     add_using_namespace (current_namespace, namespace, 0);
+ }
+ 
+ /* Combines two sets of overloaded functions into an OVERLOAD chain, removing
+    duplicates.  The first list becomes the tail of the result.
+ 
+    The algorithm is O(n^2).  We could get this down to O(n log n) by
+    doing a sort on the addresses of the functions, if that becomes
+    necessary.  */
+ 
+ static tree
+ merge_functions (tree s1, tree s2)
+ {
+   for (; s2; s2 = OVL_NEXT (s2))
+     {
+       tree fn2 = OVL_CURRENT (s2);
+       tree fns1;
+ 
+       for (fns1 = s1; fns1; fns1 = OVL_NEXT (fns1))
+ 	{
+ 	  tree fn1 = OVL_CURRENT (fns1);
+ 
+ 	  /* If the function from S2 is already in S1, there is no
+ 	     need to add it again.  For `extern "C"' functions, we
+ 	     might have two FUNCTION_DECLs for the same function, in
+ 	     different namespaces; again, we only need one of them.  */
+ 	  if (fn1 == fn2 
+ 	      || (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2)
+ 		  && DECL_NAME (fn1) == DECL_NAME (fn2)))
+ 	    break;
+ 	}
+       
+       /* If we exhausted all of the functions in S1, FN2 is new.  */
+       if (!fns1)
+ 	s1 = build_overload (fn2, s1);
+     }
+   return s1;
+ }
+ 
+ /* This should return an error not all definitions define functions.
+    It is not an error if we find two functions with exactly the
+    same signature, only if these are selected in overload resolution.
+    old is the current set of bindings, new the freshly-found binding.
+    XXX Do we want to give *all* candidates in case of ambiguity?
+    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)
+ {
+   tree val, type;
+   my_friendly_assert (old != NULL, 393);
+   /* Copy the value.  */
+   val = new->value;
+   if (val)
+     switch (TREE_CODE (val))
+       {
+       case TEMPLATE_DECL:
+         /* If we expect types or namespaces, and not templates,
+            or this is not a template class.  */
+         if (LOOKUP_QUALIFIERS_ONLY (flags)
+             && !DECL_CLASS_TEMPLATE_P (val))
+           val = NULL_TREE;
+         break;
+       case TYPE_DECL:
+         if (LOOKUP_NAMESPACES_ONLY (flags))
+           val = NULL_TREE;
+         break;
+       case NAMESPACE_DECL:
+         if (LOOKUP_TYPES_ONLY (flags))
+           val = NULL_TREE;
+         break;
+       case FUNCTION_DECL:
+         /* Ignore built-in functions that are still anticipated.  */
+         if (LOOKUP_QUALIFIERS_ONLY (flags) || DECL_ANTICIPATED (val))
+           val = NULL_TREE;
+         break;
+       default:
+         if (LOOKUP_QUALIFIERS_ONLY (flags))
+           val = NULL_TREE;
+       }
+         
+   if (!old->value)
+     old->value = val;
+   else if (val && val != old->value)
+     {
+       if (is_overloaded_fn (old->value) && is_overloaded_fn (val))
+         old->value = merge_functions (old->value, val);
+       else
+ 	{
+ 	  /* Some declarations are functions, some are not.  */
+           if (flags & LOOKUP_COMPLAIN)
+             {
+ 	      /* If we've already given this error for this lookup,
+ 		 old->value is error_mark_node, so let's not
+ 		 repeat ourselves.  */
+ 	      if (old->value != error_mark_node)
+ 		{
+ 		  error ("use of `%D' is ambiguous", name);
+ 		  cp_error_at ("  first declared as `%#D' here",
+ 			       old->value);
+ 		}
+               cp_error_at ("  also declared as `%#D' here", val);
+             }
+ 	  old->value = error_mark_node;
+ 	}
+     }
+   /* ... and copy the type.  */
+   type = new->type;
+   if (LOOKUP_NAMESPACES_ONLY (flags))
+     type = NULL_TREE;
+   if (!old->type)
+     old->type = type;
+   else if (type && old->type != type)
+     {
+       if (flags & LOOKUP_COMPLAIN)
+         {
+           error ("`%D' denotes an ambiguous type",name);
+           error ("%J  first type here", TYPE_MAIN_DECL (old->type));
+           error ("%J  other type here", TYPE_MAIN_DECL (type));
+         }
+     }
+   return old;
+ }
+ 
  /* Return the declarations that are members of the namespace NS.  */
  
  tree
*************** lookup_qualified_name (tree scope, tree 
*** 2120,2125 ****
--- 2865,2943 ----
    return error_mark_node;
  }
  
+ /* Subroutine of unualified_namespace_lookup:
+    Add the bindings of NAME in used namespaces to VAL.
+    We are currently looking for names in namespace SCOPE, so we
+    look through USINGS for using-directives of namespaces
+    which have SCOPE as a common ancestor with the current scope.
+    Returns false on errors.  */
+ 
+ bool
+ lookup_using_namespace (tree name, cxx_binding *val, tree usings, tree scope,
+                         int flags, tree *spacesp)
+ {
+   tree iter;
+   timevar_push (TV_NAME_LOOKUP);
+   /* Iterate over all used namespaces in current, searching for using
+      directives of scope.  */
+   for (iter = usings; iter; iter = TREE_CHAIN (iter))
+     if (TREE_VALUE (iter) == scope)
+       {
+         tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
+         cxx_binding *val1 =
+           cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
+         if (spacesp)
+           *spacesp = tree_cons (used, NULL_TREE, *spacesp);
+         /* Resolve ambiguities.  */
+         if (val1)
+           val = ambiguous_decl (name, val, val1, flags);
+       }
+   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
+ }
+ 
+ /* [namespace.qual]
+    Accepts the NAME to lookup and its qualifying SCOPE.
+    Returns the name/type pair found into the cxx_binding *RESULT,
+    or false on error.  */
+ 
+ bool
+ qualified_lookup_using_namespace (tree name, tree scope, cxx_binding *result,
+                                   int flags)
+ {
+   /* Maintain a list of namespaces visited...  */
+   tree seen = NULL_TREE;
+   /* ... and a list of namespace yet to see.  */
+   tree todo = NULL_TREE;
+   tree usings;
+   timevar_push (TV_NAME_LOOKUP);
+   /* Look through namespace aliases.  */
+   scope = ORIGINAL_NAMESPACE (scope);
+   while (scope && result->value != error_mark_node)
+     {
+       cxx_binding *binding =
+         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);
+       if (!result->value && !result->type)
+ 	/* Consider using directives.  */
+ 	for (usings = DECL_NAMESPACE_USING (scope); usings;
+ 	     usings = TREE_CHAIN (usings))
+ 	  /* If this was a real directive, and we have not seen it.  */
+ 	  if (!TREE_INDIRECT_USING (usings)
+ 	      && !purpose_member (TREE_PURPOSE (usings), seen))
+ 	    todo = tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
+       if (todo)
+ 	{
+ 	  scope = TREE_PURPOSE (todo);
+ 	  todo = TREE_CHAIN (todo);
+ 	}
+       else
+ 	scope = NULL_TREE; /* If there never was a todo list.  */
+     }
+   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
+ }
+ 
  /* Look up NAME in the current binding level and its superiors in the
     namespace of variables, functions and typedefs.  Return a ..._DECL
     node of some kind representing its definition if there is only one
*************** lookup_type_current_level (tree name)
*** 2303,2308 ****
--- 3121,3475 ----
      }
  
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+ }
+ 
+ /* [basic.lookup.koenig] */
+ /* A nonzero return value in the functions below indicates an error.  */
+ 
+ struct arg_lookup
+ {
+   tree name;
+   tree namespaces;
+   tree classes;
+   tree functions;
+ };
+ 
+ static bool arg_assoc (struct arg_lookup*, tree);
+ static bool arg_assoc_args (struct arg_lookup*, tree);
+ static bool arg_assoc_type (struct arg_lookup*, tree);
+ static bool add_function (struct arg_lookup *, tree);
+ static bool arg_assoc_namespace (struct arg_lookup *, tree);
+ static bool arg_assoc_class (struct arg_lookup *, tree);
+ static bool arg_assoc_template_arg (struct arg_lookup*, tree);
+ 
+ /* Add a function to the lookup structure.
+    Returns true on error.  */
+ 
+ static bool
+ add_function (struct arg_lookup *k, tree fn)
+ {
+   /* We used to check here to see if the function was already in the list,
+      but that's O(n^2), which is just too expensive for function lookup.
+      Now we deal with the occasional duplicate in joust.  In doing this, we
+      assume that the number of duplicates will be small compared to the
+      total number of functions being compared, which should usually be the
+      case.  */
+ 
+   /* We must find only functions, or exactly one non-function.  */
+   if (!k->functions) 
+     k->functions = fn;
+   else if (fn == k->functions)
+     ;
+   else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn))
+     k->functions = build_overload (fn, k->functions);
+   else
+     {
+       tree f1 = OVL_CURRENT (k->functions);
+       tree f2 = fn;
+       if (is_overloaded_fn (f1))
+ 	{
+ 	  fn = f1; f1 = f2; f2 = fn;
+ 	}
+       cp_error_at ("`%D' is not a function,", f1);
+       cp_error_at ("  conflict with `%D'", f2);
+       error ("  in call to `%D'", k->name);
+       return true;
+     }
+ 
+   return false;
+ }
+ 
+ /* Add functions of a namespace to the lookup structure.
+    Returns true on error.  */
+ 
+ static bool
+ arg_assoc_namespace (struct arg_lookup *k, tree scope)
+ {
+   tree value;
+ 
+   if (purpose_member (scope, k->namespaces))
+     return 0;
+   k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces);
+   
+   value = namespace_binding (k->name, scope);
+   if (!value)
+     return false;
+ 
+   for (; value; value = OVL_NEXT (value))
+     if (add_function (k, OVL_CURRENT (value)))
+       return true;
+   
+   return false;
+ }
+ 
+ /* Adds everything associated with a template argument to the lookup
+    structure.  Returns true on error.  */
+ 
+ static bool
+ arg_assoc_template_arg (struct arg_lookup *k, tree arg)
+ {
+   /* [basic.lookup.koenig]
+ 
+      If T is a template-id, its associated namespaces and classes are
+      ... the namespaces and classes associated with the types of the
+      template arguments provided for template type parameters
+      (excluding template template parameters); the namespaces in which
+      any template template arguments are defined; and the classes in
+      which any member templates used as template template arguments
+      are defined.  [Note: non-type template arguments do not
+      contribute to the set of associated namespaces.  ]  */
+ 
+   /* Consider first template template arguments.  */
+   if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+       || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)
+     return false;
+   else if (TREE_CODE (arg) == TEMPLATE_DECL)
+     {
+       tree ctx = CP_DECL_CONTEXT (arg);
+ 
+       /* It's not a member template.  */
+       if (TREE_CODE (ctx) == NAMESPACE_DECL)
+         return arg_assoc_namespace (k, ctx);
+       /* Otherwise, it must be member template.  */
+       else 
+         return arg_assoc_class (k, ctx);
+     }
+   /* It's not a template template argument, but it is a type template
+      argument.  */
+   else if (TYPE_P (arg))
+     return arg_assoc_type (k, arg);
+   /* It's a non-type template argument.  */
+   else
+     return false;
+ }
+ 
+ /* Adds everything associated with class to the lookup structure.
+    Returns true on error.  */
+ 
+ static bool
+ arg_assoc_class (struct arg_lookup *k, tree type)
+ {
+   tree list, friends, context;
+   int i;
+   
+   /* Backend build structures, such as __builtin_va_list, aren't
+      affected by all this.  */
+   if (!CLASS_TYPE_P (type))
+     return false;
+ 
+   if (purpose_member (type, k->classes))
+     return false;
+   k->classes = tree_cons (type, NULL_TREE, k->classes);
+   
+   context = decl_namespace (TYPE_MAIN_DECL (type));
+   if (arg_assoc_namespace (k, context))
+     return true;
+   
+   /* Process baseclasses.  */
+   for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); i++)
+     if (arg_assoc_class (k, TYPE_BINFO_BASETYPE (type, i)))
+       return true;
+   
+   /* Process friends.  */
+   for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list; 
+        list = TREE_CHAIN (list))
+     if (k->name == FRIEND_NAME (list))
+       for (friends = FRIEND_DECLS (list); friends; 
+ 	   friends = TREE_CHAIN (friends))
+ 	/* Only interested in global functions with potentially hidden
+            (i.e. unqualified) declarations.  */
+ 	if (CP_DECL_CONTEXT (TREE_VALUE (friends)) == context)
+ 	  if (add_function (k, TREE_VALUE (friends)))
+ 	    return true;
+ 
+   /* Process template arguments.  */
+   if (CLASSTYPE_TEMPLATE_INFO (type))
+     {
+       list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
+       for (i = 0; i < TREE_VEC_LENGTH (list); ++i) 
+         arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
+     }
+ 
+   return false;
+ }
+ 
+ /* Adds everything associated with a given type.
+    Returns 1 on error.  */
+ 
+ static bool
+ arg_assoc_type (struct arg_lookup *k, tree type)
+ {
+   /* As we do not get the type of non-type dependent expressions
+      right, we can end up with such things without a type.  */
+   if (!type)
+     return false;
+ 
+   if (TYPE_PTRMEM_P (type))
+     {
+       /* Pointer to member: associate class type and value type.  */
+       if (arg_assoc_type (k, TYPE_PTRMEM_CLASS_TYPE (type)))
+ 	return true;
+       return arg_assoc_type (k, TYPE_PTRMEM_POINTED_TO_TYPE (type));
+     }
+   else switch (TREE_CODE (type))
+     {
+     case ERROR_MARK:
+       return false;
+     case VOID_TYPE:
+     case INTEGER_TYPE:
+     case REAL_TYPE:
+     case COMPLEX_TYPE:
+     case VECTOR_TYPE:
+     case CHAR_TYPE:
+     case BOOLEAN_TYPE:
+       return false;
+     case RECORD_TYPE:
+       if (TYPE_PTRMEMFUNC_P (type))
+ 	return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
+       return arg_assoc_class (k, type);
+     case POINTER_TYPE:
+     case REFERENCE_TYPE:
+     case ARRAY_TYPE:
+       return arg_assoc_type (k, TREE_TYPE (type));
+     case UNION_TYPE:
+     case ENUMERAL_TYPE:
+       return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type)));
+     case METHOD_TYPE:
+       /* The basetype is referenced in the first arg type, so just
+ 	 fall through.  */
+     case FUNCTION_TYPE:
+       /* Associate the parameter types.  */
+       if (arg_assoc_args (k, TYPE_ARG_TYPES (type)))
+ 	return true;
+       /* Associate the return type.  */
+       return arg_assoc_type (k, TREE_TYPE (type));
+     case TEMPLATE_TYPE_PARM:
+     case BOUND_TEMPLATE_TEMPLATE_PARM:
+       return false;
+     case TYPENAME_TYPE:
+       return false;
+     case LANG_TYPE:
+       if (type == unknown_type_node)
+ 	return false;
+       /* else fall through */
+     default:
+       abort ();
+     }
+   return false;
+ }
+ 
+ /* Adds everything associated with arguments.  Returns true on error.  */
+ 
+ static bool
+ arg_assoc_args (struct arg_lookup *k, tree args)
+ {
+   for (; args; args = TREE_CHAIN (args))
+     if (arg_assoc (k, TREE_VALUE (args)))
+       return true;
+   return false;
+ }
+ 
+ /* Adds everything associated with a given tree_node.  Returns 1 on error.  */
+ 
+ static bool
+ arg_assoc (struct arg_lookup *k, tree n)
+ {
+   if (n == error_mark_node)
+     return false;
+ 
+   if (TYPE_P (n))
+     return arg_assoc_type (k, n);
+ 
+   if (! type_unknown_p (n))
+     return arg_assoc_type (k, TREE_TYPE (n));
+ 
+   if (TREE_CODE (n) == ADDR_EXPR)
+     n = TREE_OPERAND (n, 0);
+   if (TREE_CODE (n) == COMPONENT_REF)
+     n = TREE_OPERAND (n, 1);
+   if (TREE_CODE (n) == OFFSET_REF)
+     n = TREE_OPERAND (n, 1);
+   while (TREE_CODE (n) == TREE_LIST)
+     n = TREE_VALUE (n);
+   if (TREE_CODE (n) == BASELINK)
+     n = BASELINK_FUNCTIONS (n);
+ 
+   if (TREE_CODE (n) == FUNCTION_DECL)
+     return arg_assoc_type (k, TREE_TYPE (n));
+   if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
+     {
+       /* [basic.lookup.koenig]
+ 
+ 	 If T is a template-id, its associated namespaces and classes
+ 	 are the namespace in which the template is defined; for
+ 	 member templates, the member template's class...  */
+       tree template = TREE_OPERAND (n, 0);
+       tree args = TREE_OPERAND (n, 1);
+       tree ctx;
+       int ix;
+ 
+       if (TREE_CODE (template) == COMPONENT_REF)
+         template = TREE_OPERAND (template, 1);
+       
+       /* First, the template.  There may actually be more than one if
+ 	 this is an overloaded function template.  But, in that case,
+ 	 we only need the first; all the functions will be in the same
+ 	 namespace.  */
+       template = OVL_CURRENT (template);
+ 
+       ctx = CP_DECL_CONTEXT (template);
+        
+       if (TREE_CODE (ctx) == NAMESPACE_DECL)
+ 	{
+ 	  if (arg_assoc_namespace (k, ctx) == 1)
+ 	    return true;
+ 	}
+       /* It must be a member template.  */
+       else if (arg_assoc_class (k, ctx) == 1)
+ 	return true;
+ 
+       /* Now the arguments.  */
+       for (ix = TREE_VEC_LENGTH (args); ix--;)
+ 	if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
+ 	  return true;
+     }
+   else
+     {
+       my_friendly_assert (TREE_CODE (n) == OVERLOAD, 980715);
+       
+       for (; n; n = OVL_CHAIN (n))
+ 	if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n))))
+ 	  return true;
+     }
+ 
+   return false;
+ }
+ 
+ /* Performs Koenig lookup depending on arguments, where fns
+    are the functions found in normal lookup.  */
+ 
+ tree
+ lookup_arg_dependent (tree name, tree fns, tree args)
+ {
+   struct arg_lookup k;
+   tree fn = NULL_TREE;
+ 
+   timevar_push (TV_NAME_LOOKUP);
+   k.name = name;
+   k.functions = fns;
+   k.classes = NULL_TREE;
+ 
+   /* Note that we've already looked at some namespaces during normal
+      unqualified lookup, unless we found a decl in function scope.  */
+   if (fns)
+     fn = OVL_CURRENT (fns);
+   if (fn && TREE_CODE (fn) == FUNCTION_DECL && DECL_LOCAL_FUNCTION_P (fn))
+     k.namespaces = NULL_TREE;
+   else
+     unqualified_namespace_lookup (name, 0, &k.namespaces);
+ 
+   arg_assoc_args (&k, args);
+   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, k.functions);
  }
  
  /* Add namespace to using_directives. Return NULL_TREE if nothing was
Index: name-lookup.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.h,v
retrieving revision 1.9
diff -p -r1.9 name-lookup.h
*** name-lookup.h	13 Oct 2003 10:26:36 -0000	1.9
--- name-lookup.h	13 Oct 2003 12:56:10 -0000
*************** typedef struct cp_binding_level cxx_scop
*** 70,78 ****
     currently being defined.  */
  #define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited)
  
- /* Zero out a cxx_binding pointed to by B.  */
- #define cxx_binding_clear(B) memset ((B), 0, sizeof (cxx_binding))
- 
  struct cxx_binding GTY(())
  {
    /* Link to chain together various bindings for this name.  */
--- 70,75 ----
*************** extern tree identifier_type_value (tree)
*** 91,96 ****
--- 88,96 ----
  extern void set_identifier_type_value (tree, tree);
  extern void pop_binding (tree, tree);
  extern void clear_identifier_class_values (void);
+ extern tree constructor_name_full (tree);
+ extern tree constructor_name (tree);
+ extern bool constructor_name_p (tree, tree);
  
  /* The kinds of scopes we recognize.  */
  typedef enum scope_kind {
*************** extern void pop_from_top_level (void);
*** 267,282 ****
  extern void maybe_push_to_top_level (int);
  extern void pop_everything (void);
  extern void keep_next_level (bool);
  
  extern void push_namespace (tree);
  extern void pop_namespace (void);
  extern void push_nested_namespace (tree);
  extern void pop_nested_namespace (tree);
  extern tree push_using_directive (tree);
  extern void pushlevel_class (void);
  extern void poplevel_class (void);
- extern cxx_binding *cxx_scope_find_binding_for_name (cxx_scope *, tree);
- extern cxx_binding *binding_for_name (cxx_scope *, tree);
  extern tree pushdecl_with_scope (tree, cxx_scope *);
  extern tree lookup_tag (enum tree_code, tree, cxx_scope *, int);
  extern tree lookup_tag_reverse (tree, tree);
--- 267,284 ----
  extern void maybe_push_to_top_level (int);
  extern void pop_everything (void);
  extern void keep_next_level (bool);
+ extern bool is_ancestor (tree, tree);
+ extern void push_scope (tree);
+ extern void pop_scope (tree);
  
  extern void push_namespace (tree);
  extern void pop_namespace (void);
  extern void push_nested_namespace (tree);
  extern void pop_nested_namespace (tree);
+ extern tree namespace_ancestor (tree, tree);
  extern tree push_using_directive (tree);
  extern void pushlevel_class (void);
  extern void poplevel_class (void);
  extern tree pushdecl_with_scope (tree, cxx_scope *);
  extern tree lookup_tag (enum tree_code, tree, cxx_scope *, int);
  extern tree lookup_tag_reverse (tree, tree);
*************** extern tree lookup_name	(tree, int);
*** 284,289 ****
--- 286,293 ----
  extern tree lookup_name_real (tree, int, int, int, int);
  extern tree lookup_name_current_level (tree);
  extern tree lookup_type_current_level (tree);
+ extern bool lookup_using_namespace (tree, cxx_binding *, tree, tree, int, tree *);
+ extern bool qualified_lookup_using_namespace (tree, tree, cxx_binding *, int);
  extern tree namespace_binding (tree, tree);
  extern void add_decl_to_level (tree, cxx_scope *);
  extern void set_namespace_binding (tree, tree, tree);
*************** extern void storetags (tree);
*** 301,306 ****
--- 305,320 ----
  extern tree getdecls (void);
  extern tree cp_namespace_decls (tree);
  extern void set_class_shadows (tree);
+ extern void set_decl_namespace (tree, tree, bool);
+ extern tree current_decl_namespace (void);
+ extern void push_decl_namespace (tree);
+ extern void pop_decl_namespace (void);
+ extern void do_namespace_alias (tree, tree);
+ extern void do_toplevel_using_decl (tree);
+ extern void do_local_using_decl (tree);
+ extern tree do_class_using_decl (tree);
+ extern void do_using_directive (tree);
+ extern tree lookup_arg_dependent (tree, tree, tree);
  
  
  /* Set *DECL to the (non-hidden) declaration for ID at global scope,


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