]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
name-lookup.h (cxx_scope_find_binding_for_name): Don't export.
authorGabriel Dos Reis <gdr@integrable-solutions.net>
Tue, 14 Oct 2003 08:19:06 +0000 (08:19 +0000)
committerGabriel Dos Reis <gdr@gcc.gnu.org>
Tue, 14 Oct 2003 08:19:06 +0000 (08:19 +0000)
* 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.

From-SVN: r72462

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h

index 240f451bd09ce372265933c4cf39aefc53414d78..dd25ea37ad807893461de740cda04f2a1afbe2e5 100644 (file)
@@ -2,6 +2,45 @@
 
        * ChangeLog: Add PR number to patch for PR c++/12370.
 
+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) 
index f3286d6639053ce44b5bb6d8e7160eb44afae8a4..1d0e288c215cee17237b44e038ba0f0ae3cf3d9b 100644 (file)
@@ -3615,11 +3615,7 @@ extern void check_goto                           (tree);
 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);
@@ -3709,9 +3705,6 @@ extern tree grokfield (tree, tree, tree, tree, tree);
 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);
@@ -3723,20 +3716,8 @@ extern void import_export_decl (tree);
 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);
index c6992a5c4863773e41d95347ab4d1d2e06f1e3c0..b51e365eefd68afa7fd19fce919f59e6292a4d42 100644 (file)
@@ -64,16 +64,10 @@ typedef struct priority_info_s {
 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);
@@ -115,9 +109,6 @@ int at_eof;
 tree static_ctors;
 tree static_dtors;
 
-/* The :: namespace.  */
-
-tree global_namespace;
 \f
 /* Incorporate `const' and `volatile' qualifiers for member functions.
    FUNCTION is a TYPE_DECL or a FUNCTION_DECL.
@@ -1149,58 +1140,6 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
   if (TREE_CODE (*decl) == TYPE_DECL)
     SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
 }
-\f
-/* 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;
-}
-
 \f
 /* Defer the compilation of the FN until the end of compilation.  */
 
@@ -3013,1115 +2952,7 @@ build_offset_ref_call_from_tree (tree fn, tree args)
     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)
index 4f5999803dbfda785c29b9fe8e06680da1a20526..9f4cb78e1058f3edb5d6ae1ea59043fd3ba97d77 100644 (file)
@@ -32,6 +32,11 @@ Boston, MA 02111-1307, USA.  */
 
 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
@@ -300,6 +305,9 @@ binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
 
 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 *
@@ -1118,6 +1126,57 @@ set_identifier_type_value (tree id, tree decl)
   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 *
@@ -1134,7 +1193,7 @@ find_binding (cxx_scope *scope, cxx_binding *binding)
 
 /* Return the binding for NAME in SCOPE, if any.  Otherwise, return NULL.  */
 
-cxx_binding *
+static inline cxx_binding *
 cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)
 {
   cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
@@ -1151,7 +1210,7 @@ cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)
 /* Always returns a binding for name in scope.  If no binding is
    found, make a new one.  */
 
-cxx_binding *
+static cxx_binding *
 binding_for_name (cxx_scope *scope, tree name)
 {
   cxx_binding *result;
@@ -1198,6 +1257,218 @@ pushdecl_with_scope (tree x, cxx_scope *level)
   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.
@@ -1378,6 +1649,60 @@ lookup_tag_reverse (tree type, tree name)
     }
   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 ();
+}
 \f
 /* Do a pushlevel for class declarations.  */
 
@@ -1671,6 +1996,45 @@ push_class_level_binding (tree name, tree x)
   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)
 {
@@ -1710,6 +2074,103 @@ set_namespace_binding (tree name, tree scope, tree val)
   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.  */
 
@@ -1819,6 +2280,59 @@ pop_nested_namespace (tree ns)
   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.  */
 
@@ -1865,6 +2379,237 @@ pushdecl_namespace_level (tree x)
   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
@@ -2120,6 +2865,79 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
   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
@@ -2305,6 +3123,355 @@ lookup_type_current_level (tree name)
   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
    changed (i.e. there was already a directive), or the fresh
    TREE_LIST otherwise.  */
index 7153cbecfeb3139891f1b03ecb67b9d4dd5450fe..09ad59a76938e1f96c8b1fc46ba1858f154a5d47 100644 (file)
@@ -70,9 +70,6 @@ typedef struct cp_binding_level cxx_scope;
    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.  */
@@ -91,6 +88,9 @@ extern tree identifier_type_value (tree);
 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);
 \f
 /* The kinds of scopes we recognize.  */
 typedef enum scope_kind {
@@ -267,16 +267,18 @@ extern void pop_from_top_level (void);
 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);
 \f
 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 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);
@@ -284,6 +286,8 @@ extern tree lookup_name     (tree, int);
 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);
@@ -301,6 +305,16 @@ extern void storetags (tree);
 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,