OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc4/] [gcc/] [cp/] [name-lookup.c] - Diff between revs 283 and 519

Only display areas with differences | Details | Blame | View Log

Rev 283 Rev 519
/* Definitions for C++ name lookup routines.
/* Definitions for C++ name lookup routines.
   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
   Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
   Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
 
 
This file is part of GCC.
This file is part of GCC.
 
 
GCC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
the Free Software Foundation; either version 3, or (at your option)
any later version.
any later version.
 
 
GCC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
<http://www.gnu.org/licenses/>.  */
 
 
#include "config.h"
#include "config.h"
#include "system.h"
#include "system.h"
#include "coretypes.h"
#include "coretypes.h"
#include "tm.h"
#include "tm.h"
#include "flags.h"
#include "flags.h"
#include "tree.h"
#include "tree.h"
#include "cp-tree.h"
#include "cp-tree.h"
#include "name-lookup.h"
#include "name-lookup.h"
#include "timevar.h"
#include "timevar.h"
#include "toplev.h"
#include "toplev.h"
#include "diagnostic.h"
#include "diagnostic.h"
#include "debug.h"
#include "debug.h"
#include "c-pragma.h"
#include "c-pragma.h"
 
 
/* The bindings for a particular name in a particular scope.  */
/* The bindings for a particular name in a particular scope.  */
 
 
struct scope_binding {
struct scope_binding {
  tree value;
  tree value;
  tree type;
  tree type;
};
};
#define EMPTY_SCOPE_BINDING { NULL_TREE, NULL_TREE }
#define EMPTY_SCOPE_BINDING { NULL_TREE, NULL_TREE }
 
 
static cxx_scope *innermost_nonclass_level (void);
static cxx_scope *innermost_nonclass_level (void);
static cxx_binding *binding_for_name (cxx_scope *, tree);
static cxx_binding *binding_for_name (cxx_scope *, tree);
static tree push_overloaded_decl (tree, int, bool);
static tree push_overloaded_decl (tree, int, bool);
static bool lookup_using_namespace (tree, struct scope_binding *, tree,
static bool lookup_using_namespace (tree, struct scope_binding *, tree,
                                    tree, int);
                                    tree, int);
static bool qualified_lookup_using_namespace (tree, tree,
static bool qualified_lookup_using_namespace (tree, tree,
                                              struct scope_binding *, int);
                                              struct scope_binding *, int);
static tree lookup_type_current_level (tree);
static tree lookup_type_current_level (tree);
static tree push_using_directive (tree);
static tree push_using_directive (tree);
static cxx_binding* lookup_extern_c_fun_binding_in_all_ns (tree);
static cxx_binding* lookup_extern_c_fun_binding_in_all_ns (tree);
 
 
/* The :: namespace.  */
/* The :: namespace.  */
 
 
tree global_namespace;
tree global_namespace;
 
 
/* The name of the anonymous namespace, throughout this translation
/* The name of the anonymous namespace, throughout this translation
   unit.  */
   unit.  */
static GTY(()) tree anonymous_namespace_name;
static GTY(()) tree anonymous_namespace_name;
 
 
/* Initialize anonymous_namespace_name if necessary, and return it.  */
/* Initialize anonymous_namespace_name if necessary, and return it.  */
 
 
static tree
static tree
get_anonymous_namespace_name (void)
get_anonymous_namespace_name (void)
{
{
  if (!anonymous_namespace_name)
  if (!anonymous_namespace_name)
    {
    {
      /* The anonymous namespace has to have a unique name
      /* The anonymous namespace has to have a unique name
         if typeinfo objects are being compared by name.  */
         if typeinfo objects are being compared by name.  */
      if (! flag_weak || ! SUPPORTS_ONE_ONLY)
      if (! flag_weak || ! SUPPORTS_ONE_ONLY)
       anonymous_namespace_name = get_file_function_name ("N");
       anonymous_namespace_name = get_file_function_name ("N");
      else
      else
       /* The demangler expects anonymous namespaces to be called
       /* The demangler expects anonymous namespaces to be called
          something starting with '_GLOBAL__N_'.  */
          something starting with '_GLOBAL__N_'.  */
       anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
       anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
    }
    }
  return anonymous_namespace_name;
  return anonymous_namespace_name;
}
}
 
 
/* Compute the chain index of a binding_entry given the HASH value of its
/* Compute the chain index of a binding_entry given the HASH value of its
   name and the total COUNT of chains.  COUNT is assumed to be a power
   name and the total COUNT of chains.  COUNT is assumed to be a power
   of 2.  */
   of 2.  */
 
 
#define ENTRY_INDEX(HASH, COUNT) (((HASH) >> 3) & ((COUNT) - 1))
#define ENTRY_INDEX(HASH, COUNT) (((HASH) >> 3) & ((COUNT) - 1))
 
 
/* A free list of "binding_entry"s awaiting for re-use.  */
/* A free list of "binding_entry"s awaiting for re-use.  */
 
 
static GTY((deletable)) binding_entry free_binding_entry = NULL;
static GTY((deletable)) binding_entry free_binding_entry = NULL;
 
 
/* Create a binding_entry object for (NAME, TYPE).  */
/* Create a binding_entry object for (NAME, TYPE).  */
 
 
static inline binding_entry
static inline binding_entry
binding_entry_make (tree name, tree type)
binding_entry_make (tree name, tree type)
{
{
  binding_entry entry;
  binding_entry entry;
 
 
  if (free_binding_entry)
  if (free_binding_entry)
    {
    {
      entry = free_binding_entry;
      entry = free_binding_entry;
      free_binding_entry = entry->chain;
      free_binding_entry = entry->chain;
    }
    }
  else
  else
    entry = GGC_NEW (struct binding_entry_s);
    entry = GGC_NEW (struct binding_entry_s);
 
 
  entry->name = name;
  entry->name = name;
  entry->type = type;
  entry->type = type;
  entry->chain = NULL;
  entry->chain = NULL;
 
 
  return entry;
  return entry;
}
}
 
 
/* Put ENTRY back on the free list.  */
/* Put ENTRY back on the free list.  */
#if 0
#if 0
static inline void
static inline void
binding_entry_free (binding_entry entry)
binding_entry_free (binding_entry entry)
{
{
  entry->name = NULL;
  entry->name = NULL;
  entry->type = NULL;
  entry->type = NULL;
  entry->chain = free_binding_entry;
  entry->chain = free_binding_entry;
  free_binding_entry = entry;
  free_binding_entry = entry;
}
}
#endif
#endif
 
 
/* The datatype used to implement the mapping from names to types at
/* The datatype used to implement the mapping from names to types at
   a given scope.  */
   a given scope.  */
struct GTY(()) binding_table_s {
struct GTY(()) binding_table_s {
  /* Array of chains of "binding_entry"s  */
  /* Array of chains of "binding_entry"s  */
  binding_entry * GTY((length ("%h.chain_count"))) chain;
  binding_entry * GTY((length ("%h.chain_count"))) chain;
 
 
  /* The number of chains in this table.  This is the length of the
  /* The number of chains in this table.  This is the length of the
     member "chain" considered as an array.  */
     member "chain" considered as an array.  */
  size_t chain_count;
  size_t chain_count;
 
 
  /* Number of "binding_entry"s in this table.  */
  /* Number of "binding_entry"s in this table.  */
  size_t entry_count;
  size_t entry_count;
};
};
 
 
/* Construct TABLE with an initial CHAIN_COUNT.  */
/* Construct TABLE with an initial CHAIN_COUNT.  */
 
 
static inline void
static inline void
binding_table_construct (binding_table table, size_t chain_count)
binding_table_construct (binding_table table, size_t chain_count)
{
{
  table->chain_count = chain_count;
  table->chain_count = chain_count;
  table->entry_count = 0;
  table->entry_count = 0;
  table->chain = GGC_CNEWVEC (binding_entry, table->chain_count);
  table->chain = GGC_CNEWVEC (binding_entry, table->chain_count);
}
}
 
 
/* Make TABLE's entries ready for reuse.  */
/* Make TABLE's entries ready for reuse.  */
#if 0
#if 0
static void
static void
binding_table_free (binding_table table)
binding_table_free (binding_table table)
{
{
  size_t i;
  size_t i;
  size_t count;
  size_t count;
 
 
  if (table == NULL)
  if (table == NULL)
    return;
    return;
 
 
  for (i = 0, count = table->chain_count; i < count; ++i)
  for (i = 0, count = table->chain_count; i < count; ++i)
    {
    {
      binding_entry temp = table->chain[i];
      binding_entry temp = table->chain[i];
      while (temp != NULL)
      while (temp != NULL)
        {
        {
          binding_entry entry = temp;
          binding_entry entry = temp;
          temp = entry->chain;
          temp = entry->chain;
          binding_entry_free (entry);
          binding_entry_free (entry);
        }
        }
      table->chain[i] = NULL;
      table->chain[i] = NULL;
    }
    }
  table->entry_count = 0;
  table->entry_count = 0;
}
}
#endif
#endif
 
 
/* Allocate a table with CHAIN_COUNT, assumed to be a power of two.  */
/* Allocate a table with CHAIN_COUNT, assumed to be a power of two.  */
 
 
static inline binding_table
static inline binding_table
binding_table_new (size_t chain_count)
binding_table_new (size_t chain_count)
{
{
  binding_table table = GGC_NEW (struct binding_table_s);
  binding_table table = GGC_NEW (struct binding_table_s);
  table->chain = NULL;
  table->chain = NULL;
  binding_table_construct (table, chain_count);
  binding_table_construct (table, chain_count);
  return table;
  return table;
}
}
 
 
/* Expand TABLE to twice its current chain_count.  */
/* Expand TABLE to twice its current chain_count.  */
 
 
static void
static void
binding_table_expand (binding_table table)
binding_table_expand (binding_table table)
{
{
  const size_t old_chain_count = table->chain_count;
  const size_t old_chain_count = table->chain_count;
  const size_t old_entry_count = table->entry_count;
  const size_t old_entry_count = table->entry_count;
  const size_t new_chain_count = 2 * old_chain_count;
  const size_t new_chain_count = 2 * old_chain_count;
  binding_entry *old_chains = table->chain;
  binding_entry *old_chains = table->chain;
  size_t i;
  size_t i;
 
 
  binding_table_construct (table, new_chain_count);
  binding_table_construct (table, new_chain_count);
  for (i = 0; i < old_chain_count; ++i)
  for (i = 0; i < old_chain_count; ++i)
    {
    {
      binding_entry entry = old_chains[i];
      binding_entry entry = old_chains[i];
      for (; entry != NULL; entry = old_chains[i])
      for (; entry != NULL; entry = old_chains[i])
        {
        {
          const unsigned int hash = IDENTIFIER_HASH_VALUE (entry->name);
          const unsigned int hash = IDENTIFIER_HASH_VALUE (entry->name);
          const size_t j = ENTRY_INDEX (hash, new_chain_count);
          const size_t j = ENTRY_INDEX (hash, new_chain_count);
 
 
          old_chains[i] = entry->chain;
          old_chains[i] = entry->chain;
          entry->chain = table->chain[j];
          entry->chain = table->chain[j];
          table->chain[j] = entry;
          table->chain[j] = entry;
        }
        }
    }
    }
  table->entry_count = old_entry_count;
  table->entry_count = old_entry_count;
}
}
 
 
/* Insert a binding for NAME to TYPE into TABLE.  */
/* Insert a binding for NAME to TYPE into TABLE.  */
 
 
static void
static void
binding_table_insert (binding_table table, tree name, tree type)
binding_table_insert (binding_table table, tree name, tree type)
{
{
  const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
  const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
  const size_t i = ENTRY_INDEX (hash, table->chain_count);
  const size_t i = ENTRY_INDEX (hash, table->chain_count);
  binding_entry entry = binding_entry_make (name, type);
  binding_entry entry = binding_entry_make (name, type);
 
 
  entry->chain = table->chain[i];
  entry->chain = table->chain[i];
  table->chain[i] = entry;
  table->chain[i] = entry;
  ++table->entry_count;
  ++table->entry_count;
 
 
  if (3 * table->chain_count < 5 * table->entry_count)
  if (3 * table->chain_count < 5 * table->entry_count)
    binding_table_expand (table);
    binding_table_expand (table);
}
}
 
 
/* Return the binding_entry, if any, that maps NAME.  */
/* Return the binding_entry, if any, that maps NAME.  */
 
 
binding_entry
binding_entry
binding_table_find (binding_table table, tree name)
binding_table_find (binding_table table, tree name)
{
{
  const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
  const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
  binding_entry entry = table->chain[ENTRY_INDEX (hash, table->chain_count)];
  binding_entry entry = table->chain[ENTRY_INDEX (hash, table->chain_count)];
 
 
  while (entry != NULL && entry->name != name)
  while (entry != NULL && entry->name != name)
    entry = entry->chain;
    entry = entry->chain;
 
 
  return entry;
  return entry;
}
}
 
 
/* Apply PROC -- with DATA -- to all entries in TABLE.  */
/* Apply PROC -- with DATA -- to all entries in TABLE.  */
 
 
void
void
binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
{
{
  const size_t chain_count = table->chain_count;
  const size_t chain_count = table->chain_count;
  size_t i;
  size_t i;
 
 
  for (i = 0; i < chain_count; ++i)
  for (i = 0; i < chain_count; ++i)
    {
    {
      binding_entry entry = table->chain[i];
      binding_entry entry = table->chain[i];
      for (; entry != NULL; entry = entry->chain)
      for (; entry != NULL; entry = entry->chain)
        proc (entry, data);
        proc (entry, data);
    }
    }
}
}


#ifndef ENABLE_SCOPE_CHECKING
#ifndef ENABLE_SCOPE_CHECKING
#  define ENABLE_SCOPE_CHECKING 0
#  define ENABLE_SCOPE_CHECKING 0
#else
#else
#  define ENABLE_SCOPE_CHECKING 1
#  define ENABLE_SCOPE_CHECKING 1
#endif
#endif
 
 
/* A free list of "cxx_binding"s, connected by their PREVIOUS.  */
/* A free list of "cxx_binding"s, connected by their PREVIOUS.  */
 
 
static GTY((deletable)) cxx_binding *free_bindings;
static GTY((deletable)) cxx_binding *free_bindings;
 
 
/* Initialize VALUE and TYPE field for BINDING, and set the PREVIOUS
/* Initialize VALUE and TYPE field for BINDING, and set the PREVIOUS
   field to NULL.  */
   field to NULL.  */
 
 
static inline void
static inline void
cxx_binding_init (cxx_binding *binding, tree value, tree type)
cxx_binding_init (cxx_binding *binding, tree value, tree type)
{
{
  binding->value = value;
  binding->value = value;
  binding->type = type;
  binding->type = type;
  binding->previous = NULL;
  binding->previous = NULL;
}
}
 
 
/* (GC)-allocate a binding object with VALUE and TYPE member initialized.  */
/* (GC)-allocate a binding object with VALUE and TYPE member initialized.  */
 
 
static cxx_binding *
static cxx_binding *
cxx_binding_make (tree value, tree type)
cxx_binding_make (tree value, tree type)
{
{
  cxx_binding *binding;
  cxx_binding *binding;
  if (free_bindings)
  if (free_bindings)
    {
    {
      binding = free_bindings;
      binding = free_bindings;
      free_bindings = binding->previous;
      free_bindings = binding->previous;
    }
    }
  else
  else
    binding = GGC_NEW (cxx_binding);
    binding = GGC_NEW (cxx_binding);
 
 
  cxx_binding_init (binding, value, type);
  cxx_binding_init (binding, value, type);
 
 
  return binding;
  return binding;
}
}
 
 
/* Put BINDING back on the free list.  */
/* Put BINDING back on the free list.  */
 
 
static inline void
static inline void
cxx_binding_free (cxx_binding *binding)
cxx_binding_free (cxx_binding *binding)
{
{
  binding->scope = NULL;
  binding->scope = NULL;
  binding->previous = free_bindings;
  binding->previous = free_bindings;
  free_bindings = binding;
  free_bindings = binding;
}
}
 
 
/* Create a new binding for NAME (with the indicated VALUE and TYPE
/* Create a new binding for NAME (with the indicated VALUE and TYPE
   bindings) in the class scope indicated by SCOPE.  */
   bindings) in the class scope indicated by SCOPE.  */
 
 
static cxx_binding *
static cxx_binding *
new_class_binding (tree name, tree value, tree type, cxx_scope *scope)
new_class_binding (tree name, tree value, tree type, cxx_scope *scope)
{
{
  cp_class_binding *cb;
  cp_class_binding *cb;
  cxx_binding *binding;
  cxx_binding *binding;
 
 
  if (VEC_length (cp_class_binding, scope->class_shadowed))
  if (VEC_length (cp_class_binding, scope->class_shadowed))
    {
    {
      cp_class_binding *old_base;
      cp_class_binding *old_base;
      old_base = VEC_index (cp_class_binding, scope->class_shadowed, 0);
      old_base = VEC_index (cp_class_binding, scope->class_shadowed, 0);
      if (VEC_reserve (cp_class_binding, gc, scope->class_shadowed, 1))
      if (VEC_reserve (cp_class_binding, gc, scope->class_shadowed, 1))
        {
        {
          /* Fixup the current bindings, as they might have moved.  */
          /* Fixup the current bindings, as they might have moved.  */
          size_t i;
          size_t i;
 
 
          for (i = 0;
          for (i = 0;
               VEC_iterate (cp_class_binding, scope->class_shadowed, i, cb);
               VEC_iterate (cp_class_binding, scope->class_shadowed, i, cb);
               i++)
               i++)
            {
            {
              cxx_binding **b;
              cxx_binding **b;
              b = &IDENTIFIER_BINDING (cb->identifier);
              b = &IDENTIFIER_BINDING (cb->identifier);
              while (*b != &old_base[i].base)
              while (*b != &old_base[i].base)
                b = &((*b)->previous);
                b = &((*b)->previous);
              *b = &cb->base;
              *b = &cb->base;
            }
            }
        }
        }
      cb = VEC_quick_push (cp_class_binding, scope->class_shadowed, NULL);
      cb = VEC_quick_push (cp_class_binding, scope->class_shadowed, NULL);
    }
    }
  else
  else
    cb = VEC_safe_push (cp_class_binding, gc, scope->class_shadowed, NULL);
    cb = VEC_safe_push (cp_class_binding, gc, scope->class_shadowed, NULL);
 
 
  cb->identifier = name;
  cb->identifier = name;
  binding = &cb->base;
  binding = &cb->base;
  binding->scope = scope;
  binding->scope = scope;
  cxx_binding_init (binding, value, type);
  cxx_binding_init (binding, value, type);
  return binding;
  return binding;
}
}
 
 
/* Make DECL the innermost binding for ID.  The LEVEL is the binding
/* Make DECL the innermost binding for ID.  The LEVEL is the binding
   level at which this declaration is being bound.  */
   level at which this declaration is being bound.  */
 
 
static void
static void
push_binding (tree id, tree decl, cxx_scope* level)
push_binding (tree id, tree decl, cxx_scope* level)
{
{
  cxx_binding *binding;
  cxx_binding *binding;
 
 
  if (level != class_binding_level)
  if (level != class_binding_level)
    {
    {
      binding = cxx_binding_make (decl, NULL_TREE);
      binding = cxx_binding_make (decl, NULL_TREE);
      binding->scope = level;
      binding->scope = level;
    }
    }
  else
  else
    binding = new_class_binding (id, decl, /*type=*/NULL_TREE, level);
    binding = new_class_binding (id, decl, /*type=*/NULL_TREE, level);
 
 
  /* Now, fill in the binding information.  */
  /* Now, fill in the binding information.  */
  binding->previous = IDENTIFIER_BINDING (id);
  binding->previous = IDENTIFIER_BINDING (id);
  INHERITED_VALUE_BINDING_P (binding) = 0;
  INHERITED_VALUE_BINDING_P (binding) = 0;
  LOCAL_BINDING_P (binding) = (level != class_binding_level);
  LOCAL_BINDING_P (binding) = (level != class_binding_level);
 
 
  /* And put it on the front of the list of bindings for ID.  */
  /* And put it on the front of the list of bindings for ID.  */
  IDENTIFIER_BINDING (id) = binding;
  IDENTIFIER_BINDING (id) = binding;
}
}
 
 
/* Remove the binding for DECL which should be the innermost binding
/* Remove the binding for DECL which should be the innermost binding
   for ID.  */
   for ID.  */
 
 
void
void
pop_binding (tree id, tree decl)
pop_binding (tree id, tree decl)
{
{
  cxx_binding *binding;
  cxx_binding *binding;
 
 
  if (id == NULL_TREE)
  if (id == NULL_TREE)
    /* It's easiest to write the loops that call this function without
    /* It's easiest to write the loops that call this function without
       checking whether or not the entities involved have names.  We
       checking whether or not the entities involved have names.  We
       get here for such an entity.  */
       get here for such an entity.  */
    return;
    return;
 
 
  /* Get the innermost binding for ID.  */
  /* Get the innermost binding for ID.  */
  binding = IDENTIFIER_BINDING (id);
  binding = IDENTIFIER_BINDING (id);
 
 
  /* The name should be bound.  */
  /* The name should be bound.  */
  gcc_assert (binding != NULL);
  gcc_assert (binding != NULL);
 
 
  /* The DECL will be either the ordinary binding or the type
  /* The DECL will be either the ordinary binding or the type
     binding for this identifier.  Remove that binding.  */
     binding for this identifier.  Remove that binding.  */
  if (binding->value == decl)
  if (binding->value == decl)
    binding->value = NULL_TREE;
    binding->value = NULL_TREE;
  else
  else
    {
    {
      gcc_assert (binding->type == decl);
      gcc_assert (binding->type == decl);
      binding->type = NULL_TREE;
      binding->type = NULL_TREE;
    }
    }
 
 
  if (!binding->value && !binding->type)
  if (!binding->value && !binding->type)
    {
    {
      /* We're completely done with the innermost binding for this
      /* We're completely done with the innermost binding for this
         identifier.  Unhook it from the list of bindings.  */
         identifier.  Unhook it from the list of bindings.  */
      IDENTIFIER_BINDING (id) = binding->previous;
      IDENTIFIER_BINDING (id) = binding->previous;
 
 
      /* Add it to the free list.  */
      /* Add it to the free list.  */
      cxx_binding_free (binding);
      cxx_binding_free (binding);
    }
    }
}
}
 
 
/* BINDING records an existing declaration for a name in the current scope.
/* BINDING records an existing declaration for a name in the current scope.
   But, DECL is another declaration for that same identifier in the
   But, DECL is another declaration for that same identifier in the
   same scope.  This is the `struct stat' hack whereby a non-typedef
   same scope.  This is the `struct stat' hack whereby a non-typedef
   class name or enum-name can be bound at the same level as some other
   class name or enum-name can be bound at the same level as some other
   kind of entity.
   kind of entity.
   3.3.7/1
   3.3.7/1
 
 
     A class name (9.1) or enumeration name (7.2) can be hidden by the
     A class name (9.1) or enumeration name (7.2) can be hidden by the
     name of an object, function, or enumerator declared in the same scope.
     name of an object, function, or enumerator declared in the same scope.
     If a class or enumeration name and an object, function, or enumerator
     If a class or enumeration name and an object, function, or enumerator
     are declared in the same scope (in any order) with the same name, the
     are declared in the same scope (in any order) with the same name, the
     class or enumeration name is hidden wherever the object, function, or
     class or enumeration name is hidden wherever the object, function, or
     enumerator name is visible.
     enumerator name is visible.
 
 
   It's the responsibility of the caller to check that
   It's the responsibility of the caller to check that
   inserting this name is valid here.  Returns nonzero if the new binding
   inserting this name is valid here.  Returns nonzero if the new binding
   was successful.  */
   was successful.  */
 
 
static bool
static bool
supplement_binding (cxx_binding *binding, tree decl)
supplement_binding (cxx_binding *binding, tree decl)
{
{
  tree bval = binding->value;
  tree bval = binding->value;
  bool ok = true;
  bool ok = true;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
  if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
    /* The new name is the type name.  */
    /* The new name is the type name.  */
    binding->type = decl;
    binding->type = decl;
  else if (/* BVAL is null when push_class_level_binding moves an
  else if (/* BVAL is null when push_class_level_binding moves an
              inherited type-binding out of the way to make room for a
              inherited type-binding out of the way to make room for a
              new value binding.  */
              new value binding.  */
           !bval
           !bval
           /* BVAL is error_mark_node when DECL's name has been used
           /* BVAL is error_mark_node when DECL's name has been used
              in a non-class scope prior declaration.  In that case,
              in a non-class scope prior declaration.  In that case,
              we should have already issued a diagnostic; for graceful
              we should have already issued a diagnostic; for graceful
              error recovery purpose, pretend this was the intended
              error recovery purpose, pretend this was the intended
              declaration for that name.  */
              declaration for that name.  */
           || bval == error_mark_node
           || bval == error_mark_node
           /* If BVAL is anticipated but has not yet been declared,
           /* If BVAL is anticipated but has not yet been declared,
              pretend it is not there at all.  */
              pretend it is not there at all.  */
           || (TREE_CODE (bval) == FUNCTION_DECL
           || (TREE_CODE (bval) == FUNCTION_DECL
               && DECL_ANTICIPATED (bval)
               && DECL_ANTICIPATED (bval)
               && !DECL_HIDDEN_FRIEND_P (bval)))
               && !DECL_HIDDEN_FRIEND_P (bval)))
    binding->value = decl;
    binding->value = decl;
  else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval))
  else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval))
    {
    {
      /* The old binding was a type name.  It was placed in
      /* The old binding was a type name.  It was placed in
         VALUE field because it was thought, at the point it was
         VALUE field because it was thought, at the point it was
         declared, to be the only entity with such a name.  Move the
         declared, to be the only entity with such a name.  Move the
         type name into the type slot; it is now hidden by the new
         type name into the type slot; it is now hidden by the new
         binding.  */
         binding.  */
      binding->type = bval;
      binding->type = bval;
      binding->value = decl;
      binding->value = decl;
      binding->value_is_inherited = false;
      binding->value_is_inherited = false;
    }
    }
  else if (TREE_CODE (bval) == TYPE_DECL
  else if (TREE_CODE (bval) == TYPE_DECL
           && TREE_CODE (decl) == TYPE_DECL
           && TREE_CODE (decl) == TYPE_DECL
           && DECL_NAME (decl) == DECL_NAME (bval)
           && DECL_NAME (decl) == DECL_NAME (bval)
           && binding->scope->kind != sk_class
           && binding->scope->kind != sk_class
           && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))
           && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))
               /* If either type involves template parameters, we must
               /* If either type involves template parameters, we must
                  wait until instantiation.  */
                  wait until instantiation.  */
               || uses_template_parms (TREE_TYPE (decl))
               || uses_template_parms (TREE_TYPE (decl))
               || uses_template_parms (TREE_TYPE (bval))))
               || uses_template_parms (TREE_TYPE (bval))))
    /* We have two typedef-names, both naming the same type to have
    /* We have two typedef-names, both naming the same type to have
       the same name.  In general, this is OK because of:
       the same name.  In general, this is OK because of:
 
 
         [dcl.typedef]
         [dcl.typedef]
 
 
         In a given scope, a typedef specifier can be used to redefine
         In a given scope, a typedef specifier can be used to redefine
         the name of any type declared in that scope to refer to the
         the name of any type declared in that scope to refer to the
         type to which it already refers.
         type to which it already refers.
 
 
       However, in class scopes, this rule does not apply due to the
       However, in class scopes, this rule does not apply due to the
       stricter language in [class.mem] prohibiting redeclarations of
       stricter language in [class.mem] prohibiting redeclarations of
       members.  */
       members.  */
    ok = false;
    ok = false;
  /* There can be two block-scope declarations of the same variable,
  /* There can be two block-scope declarations of the same variable,
     so long as they are `extern' declarations.  However, there cannot
     so long as they are `extern' declarations.  However, there cannot
     be two declarations of the same static data member:
     be two declarations of the same static data member:
 
 
       [class.mem]
       [class.mem]
 
 
       A member shall not be declared twice in the
       A member shall not be declared twice in the
       member-specification.  */
       member-specification.  */
  else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (bval) == VAR_DECL
  else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (bval) == VAR_DECL
           && DECL_EXTERNAL (decl) && DECL_EXTERNAL (bval)
           && DECL_EXTERNAL (decl) && DECL_EXTERNAL (bval)
           && !DECL_CLASS_SCOPE_P (decl))
           && !DECL_CLASS_SCOPE_P (decl))
    {
    {
      duplicate_decls (decl, binding->value, /*newdecl_is_friend=*/false);
      duplicate_decls (decl, binding->value, /*newdecl_is_friend=*/false);
      ok = false;
      ok = false;
    }
    }
  else if (TREE_CODE (decl) == NAMESPACE_DECL
  else if (TREE_CODE (decl) == NAMESPACE_DECL
           && TREE_CODE (bval) == NAMESPACE_DECL
           && TREE_CODE (bval) == NAMESPACE_DECL
           && DECL_NAMESPACE_ALIAS (decl)
           && DECL_NAMESPACE_ALIAS (decl)
           && DECL_NAMESPACE_ALIAS (bval)
           && DECL_NAMESPACE_ALIAS (bval)
           && ORIGINAL_NAMESPACE (bval) == ORIGINAL_NAMESPACE (decl))
           && ORIGINAL_NAMESPACE (bval) == ORIGINAL_NAMESPACE (decl))
    /* [namespace.alias]
    /* [namespace.alias]
 
 
      In a declarative region, a namespace-alias-definition can be
      In a declarative region, a namespace-alias-definition can be
      used to redefine a namespace-alias declared in that declarative
      used to redefine a namespace-alias declared in that declarative
      region to refer only to the namespace to which it already
      region to refer only to the namespace to which it already
      refers.  */
      refers.  */
    ok = false;
    ok = false;
  else
  else
    {
    {
      error ("declaration of %q#D", decl);
      error ("declaration of %q#D", decl);
      error ("conflicts with previous declaration %q+#D", bval);
      error ("conflicts with previous declaration %q+#D", bval);
      ok = false;
      ok = false;
    }
    }
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
}
}
 
 
/* Add DECL to the list of things declared in B.  */
/* Add DECL to the list of things declared in B.  */
 
 
static void
static void
add_decl_to_level (tree decl, cxx_scope *b)
add_decl_to_level (tree decl, cxx_scope *b)
{
{
  /* We used to record virtual tables as if they were ordinary
  /* We used to record virtual tables as if they were ordinary
     variables, but no longer do so.  */
     variables, but no longer do so.  */
  gcc_assert (!(TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl)));
  gcc_assert (!(TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl)));
 
 
  if (TREE_CODE (decl) == NAMESPACE_DECL
  if (TREE_CODE (decl) == NAMESPACE_DECL
      && !DECL_NAMESPACE_ALIAS (decl))
      && !DECL_NAMESPACE_ALIAS (decl))
    {
    {
      TREE_CHAIN (decl) = b->namespaces;
      TREE_CHAIN (decl) = b->namespaces;
      b->namespaces = decl;
      b->namespaces = decl;
    }
    }
  else
  else
    {
    {
      /* We build up the list in reverse order, and reverse it later if
      /* We build up the list in reverse order, and reverse it later if
         necessary.  */
         necessary.  */
      TREE_CHAIN (decl) = b->names;
      TREE_CHAIN (decl) = b->names;
      b->names = decl;
      b->names = decl;
      b->names_size++;
      b->names_size++;
 
 
      /* If appropriate, add decl to separate list of statics.  We
      /* If appropriate, add decl to separate list of statics.  We
         include extern variables because they might turn out to be
         include extern variables because they might turn out to be
         static later.  It's OK for this list to contain a few false
         static later.  It's OK for this list to contain a few false
         positives.  */
         positives.  */
      if (b->kind == sk_namespace)
      if (b->kind == sk_namespace)
        if ((TREE_CODE (decl) == VAR_DECL
        if ((TREE_CODE (decl) == VAR_DECL
             && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
             && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
            || (TREE_CODE (decl) == FUNCTION_DECL
            || (TREE_CODE (decl) == FUNCTION_DECL
                && (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl))))
                && (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl))))
          VEC_safe_push (tree, gc, b->static_decls, decl);
          VEC_safe_push (tree, gc, b->static_decls, decl);
    }
    }
}
}
 
 
/* Record a decl-node X as belonging to the current lexical scope.
/* Record a decl-node X as belonging to the current lexical scope.
   Check for errors (such as an incompatible declaration for the same
   Check for errors (such as an incompatible declaration for the same
   name already seen in the same scope).  IS_FRIEND is true if X is
   name already seen in the same scope).  IS_FRIEND is true if X is
   declared as a friend.
   declared as a friend.
 
 
   Returns either X or an old decl for the same name.
   Returns either X or an old decl for the same name.
   If an old decl is returned, it may have been smashed
   If an old decl is returned, it may have been smashed
   to agree with what X says.  */
   to agree with what X says.  */
 
 
tree
tree
pushdecl_maybe_friend (tree x, bool is_friend)
pushdecl_maybe_friend (tree x, bool is_friend)
{
{
  tree t;
  tree t;
  tree name;
  tree name;
  int need_new_binding;
  int need_new_binding;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
 
 
  if (x == error_mark_node)
  if (x == error_mark_node)
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
 
  need_new_binding = 1;
  need_new_binding = 1;
 
 
  if (DECL_TEMPLATE_PARM_P (x))
  if (DECL_TEMPLATE_PARM_P (x))
    /* Template parameters have no context; they are not X::T even
    /* Template parameters have no context; they are not X::T even
       when declared within a class or namespace.  */
       when declared within a class or namespace.  */
    ;
    ;
  else
  else
    {
    {
      if (current_function_decl && x != current_function_decl
      if (current_function_decl && x != current_function_decl
          /* A local declaration for a function doesn't constitute
          /* A local declaration for a function doesn't constitute
             nesting.  */
             nesting.  */
          && TREE_CODE (x) != FUNCTION_DECL
          && TREE_CODE (x) != FUNCTION_DECL
          /* A local declaration for an `extern' variable is in the
          /* A local declaration for an `extern' variable is in the
             scope of the current namespace, not the current
             scope of the current namespace, not the current
             function.  */
             function.  */
          && !(TREE_CODE (x) == VAR_DECL && DECL_EXTERNAL (x))
          && !(TREE_CODE (x) == VAR_DECL && DECL_EXTERNAL (x))
          /* When parsing the parameter list of a function declarator,
          /* When parsing the parameter list of a function declarator,
             don't set DECL_CONTEXT to an enclosing function.  When we
             don't set DECL_CONTEXT to an enclosing function.  When we
             push the PARM_DECLs in order to process the function body,
             push the PARM_DECLs in order to process the function body,
             current_binding_level->this_entity will be set.  */
             current_binding_level->this_entity will be set.  */
          && !(TREE_CODE (x) == PARM_DECL
          && !(TREE_CODE (x) == PARM_DECL
               && current_binding_level->kind == sk_function_parms
               && current_binding_level->kind == sk_function_parms
               && current_binding_level->this_entity == NULL)
               && current_binding_level->this_entity == NULL)
          && !DECL_CONTEXT (x))
          && !DECL_CONTEXT (x))
        DECL_CONTEXT (x) = current_function_decl;
        DECL_CONTEXT (x) = current_function_decl;
 
 
      /* If this is the declaration for a namespace-scope function,
      /* If this is the declaration for a namespace-scope function,
         but the declaration itself is in a local scope, mark the
         but the declaration itself is in a local scope, mark the
         declaration.  */
         declaration.  */
      if (TREE_CODE (x) == FUNCTION_DECL
      if (TREE_CODE (x) == FUNCTION_DECL
          && DECL_NAMESPACE_SCOPE_P (x)
          && DECL_NAMESPACE_SCOPE_P (x)
          && current_function_decl
          && current_function_decl
          && x != current_function_decl)
          && x != current_function_decl)
        DECL_LOCAL_FUNCTION_P (x) = 1;
        DECL_LOCAL_FUNCTION_P (x) = 1;
    }
    }
 
 
  name = DECL_NAME (x);
  name = DECL_NAME (x);
  if (name)
  if (name)
    {
    {
      int different_binding_level = 0;
      int different_binding_level = 0;
 
 
      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
        name = TREE_OPERAND (name, 0);
        name = TREE_OPERAND (name, 0);
 
 
      /* In case this decl was explicitly namespace-qualified, look it
      /* In case this decl was explicitly namespace-qualified, look it
         up in its namespace context.  */
         up in its namespace context.  */
      if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())
      if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())
        t = namespace_binding (name, DECL_CONTEXT (x));
        t = namespace_binding (name, DECL_CONTEXT (x));
      else
      else
        t = lookup_name_innermost_nonclass_level (name);
        t = lookup_name_innermost_nonclass_level (name);
 
 
      /* [basic.link] If there is a visible declaration of an entity
      /* [basic.link] If there is a visible declaration of an entity
         with linkage having the same name and type, ignoring entities
         with linkage having the same name and type, ignoring entities
         declared outside the innermost enclosing namespace scope, the
         declared outside the innermost enclosing namespace scope, the
         block scope declaration declares that same entity and
         block scope declaration declares that same entity and
         receives the linkage of the previous declaration.  */
         receives the linkage of the previous declaration.  */
      if (! t && current_function_decl && x != current_function_decl
      if (! t && current_function_decl && x != current_function_decl
          && (TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
          && (TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
          && DECL_EXTERNAL (x))
          && DECL_EXTERNAL (x))
        {
        {
          /* Look in block scope.  */
          /* Look in block scope.  */
          t = innermost_non_namespace_value (name);
          t = innermost_non_namespace_value (name);
          /* Or in the innermost namespace.  */
          /* Or in the innermost namespace.  */
          if (! t)
          if (! t)
            t = namespace_binding (name, DECL_CONTEXT (x));
            t = namespace_binding (name, DECL_CONTEXT (x));
          /* Does it have linkage?  Note that if this isn't a DECL, it's an
          /* Does it have linkage?  Note that if this isn't a DECL, it's an
             OVERLOAD, which is OK.  */
             OVERLOAD, which is OK.  */
          if (t && DECL_P (t) && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
          if (t && DECL_P (t) && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
            t = NULL_TREE;
            t = NULL_TREE;
          if (t)
          if (t)
            different_binding_level = 1;
            different_binding_level = 1;
        }
        }
 
 
      /* If we are declaring a function, and the result of name-lookup
      /* If we are declaring a function, and the result of name-lookup
         was an OVERLOAD, look for an overloaded instance that is
         was an OVERLOAD, look for an overloaded instance that is
         actually the same as the function we are declaring.  (If
         actually the same as the function we are declaring.  (If
         there is one, we have to merge our declaration with the
         there is one, we have to merge our declaration with the
         previous declaration.)  */
         previous declaration.)  */
      if (t && TREE_CODE (t) == OVERLOAD)
      if (t && TREE_CODE (t) == OVERLOAD)
        {
        {
          tree match;
          tree match;
 
 
          if (TREE_CODE (x) == FUNCTION_DECL)
          if (TREE_CODE (x) == FUNCTION_DECL)
            for (match = t; match; match = OVL_NEXT (match))
            for (match = t; match; match = OVL_NEXT (match))
              {
              {
                if (decls_match (OVL_CURRENT (match), x))
                if (decls_match (OVL_CURRENT (match), x))
                  break;
                  break;
              }
              }
          else
          else
            /* Just choose one.  */
            /* Just choose one.  */
            match = t;
            match = t;
 
 
          if (match)
          if (match)
            t = OVL_CURRENT (match);
            t = OVL_CURRENT (match);
          else
          else
            t = NULL_TREE;
            t = NULL_TREE;
        }
        }
 
 
      if (t && t != error_mark_node)
      if (t && t != error_mark_node)
        {
        {
          if (different_binding_level)
          if (different_binding_level)
            {
            {
              if (decls_match (x, t))
              if (decls_match (x, t))
                /* The standard only says that the local extern
                /* The standard only says that the local extern
                   inherits linkage from the previous decl; in
                   inherits linkage from the previous decl; in
                   particular, default args are not shared.  Add
                   particular, default args are not shared.  Add
                   the decl into a hash table to make sure only
                   the decl into a hash table to make sure only
                   the previous decl in this case is seen by the
                   the previous decl in this case is seen by the
                   middle end.  */
                   middle end.  */
                {
                {
                  struct cxx_int_tree_map *h;
                  struct cxx_int_tree_map *h;
                  void **loc;
                  void **loc;
 
 
                  TREE_PUBLIC (x) = TREE_PUBLIC (t);
                  TREE_PUBLIC (x) = TREE_PUBLIC (t);
 
 
                  if (cp_function_chain->extern_decl_map == NULL)
                  if (cp_function_chain->extern_decl_map == NULL)
                    cp_function_chain->extern_decl_map
                    cp_function_chain->extern_decl_map
                      = htab_create_ggc (20, cxx_int_tree_map_hash,
                      = htab_create_ggc (20, cxx_int_tree_map_hash,
                                         cxx_int_tree_map_eq, NULL);
                                         cxx_int_tree_map_eq, NULL);
 
 
                  h = GGC_NEW (struct cxx_int_tree_map);
                  h = GGC_NEW (struct cxx_int_tree_map);
                  h->uid = DECL_UID (x);
                  h->uid = DECL_UID (x);
                  h->to = t;
                  h->to = t;
                  loc = htab_find_slot_with_hash
                  loc = htab_find_slot_with_hash
                          (cp_function_chain->extern_decl_map, h,
                          (cp_function_chain->extern_decl_map, h,
                           h->uid, INSERT);
                           h->uid, INSERT);
                  *(struct cxx_int_tree_map **) loc = h;
                  *(struct cxx_int_tree_map **) loc = h;
                }
                }
            }
            }
          else if (TREE_CODE (t) == PARM_DECL)
          else if (TREE_CODE (t) == PARM_DECL)
            {
            {
              /* Check for duplicate params.  */
              /* Check for duplicate params.  */
              tree d = duplicate_decls (x, t, is_friend);
              tree d = duplicate_decls (x, t, is_friend);
              if (d)
              if (d)
                POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, d);
                POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, d);
            }
            }
          else if ((DECL_EXTERN_C_FUNCTION_P (x)
          else if ((DECL_EXTERN_C_FUNCTION_P (x)
                    || DECL_FUNCTION_TEMPLATE_P (x))
                    || DECL_FUNCTION_TEMPLATE_P (x))
                   && is_overloaded_fn (t))
                   && is_overloaded_fn (t))
            /* Don't do anything just yet.  */;
            /* Don't do anything just yet.  */;
          else if (t == wchar_decl_node)
          else if (t == wchar_decl_node)
            {
            {
              if (! DECL_IN_SYSTEM_HEADER (x))
              if (! DECL_IN_SYSTEM_HEADER (x))
                pedwarn (input_location, OPT_pedantic, "redeclaration of %<wchar_t%> as %qT",
                pedwarn (input_location, OPT_pedantic, "redeclaration of %<wchar_t%> as %qT",
                         TREE_TYPE (x));
                         TREE_TYPE (x));
 
 
              /* Throw away the redeclaration.  */
              /* Throw away the redeclaration.  */
              POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
              POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
            }
            }
          else
          else
            {
            {
              tree olddecl = duplicate_decls (x, t, is_friend);
              tree olddecl = duplicate_decls (x, t, is_friend);
 
 
              /* If the redeclaration failed, we can stop at this
              /* If the redeclaration failed, we can stop at this
                 point.  */
                 point.  */
              if (olddecl == error_mark_node)
              if (olddecl == error_mark_node)
                POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
                POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
 
              if (olddecl)
              if (olddecl)
                {
                {
                  if (TREE_CODE (t) == TYPE_DECL)
                  if (TREE_CODE (t) == TYPE_DECL)
                    SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
                    SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
 
 
                  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
                  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
                }
                }
              else if (DECL_MAIN_P (x) && TREE_CODE (t) == FUNCTION_DECL)
              else if (DECL_MAIN_P (x) && TREE_CODE (t) == FUNCTION_DECL)
                {
                {
                  /* A redeclaration of main, but not a duplicate of the
                  /* A redeclaration of main, but not a duplicate of the
                     previous one.
                     previous one.
 
 
                     [basic.start.main]
                     [basic.start.main]
 
 
                     This function shall not be overloaded.  */
                     This function shall not be overloaded.  */
                  error ("invalid redeclaration of %q+D", t);
                  error ("invalid redeclaration of %q+D", t);
                  error ("as %qD", x);
                  error ("as %qD", x);
                  /* We don't try to push this declaration since that
                  /* We don't try to push this declaration since that
                     causes a crash.  */
                     causes a crash.  */
                  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
                  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
                }
                }
            }
            }
        }
        }
 
 
      /* If x has C linkage-specification, (extern "C"),
      /* If x has C linkage-specification, (extern "C"),
         lookup its binding, in case it's already bound to an object.
         lookup its binding, in case it's already bound to an object.
         The lookup is done in all namespaces.
         The lookup is done in all namespaces.
         If we find an existing binding, make sure it has the same
         If we find an existing binding, make sure it has the same
         exception specification as x, otherwise, bail in error [7.5, 7.6].  */
         exception specification as x, otherwise, bail in error [7.5, 7.6].  */
      if ((TREE_CODE (x) == FUNCTION_DECL)
      if ((TREE_CODE (x) == FUNCTION_DECL)
          && DECL_EXTERN_C_P (x)
          && DECL_EXTERN_C_P (x)
          /* We should ignore declarations happening in system headers.  */
          /* We should ignore declarations happening in system headers.  */
          && !DECL_ARTIFICIAL (x)
          && !DECL_ARTIFICIAL (x)
          && !DECL_IN_SYSTEM_HEADER (x))
          && !DECL_IN_SYSTEM_HEADER (x))
        {
        {
          cxx_binding *function_binding =
          cxx_binding *function_binding =
              lookup_extern_c_fun_binding_in_all_ns (x);
              lookup_extern_c_fun_binding_in_all_ns (x);
          tree previous = (function_binding
          tree previous = (function_binding
                           ? function_binding->value
                           ? function_binding->value
                           : NULL_TREE);
                           : NULL_TREE);
          if (previous
          if (previous
              && !DECL_ARTIFICIAL (previous)
              && !DECL_ARTIFICIAL (previous)
              && !DECL_IN_SYSTEM_HEADER (previous)
              && !DECL_IN_SYSTEM_HEADER (previous)
              && DECL_CONTEXT (previous) != DECL_CONTEXT (x))
              && DECL_CONTEXT (previous) != DECL_CONTEXT (x))
            {
            {
              tree previous = function_binding->value;
              tree previous = function_binding->value;
 
 
              /* In case either x or previous is declared to throw an exception,
              /* In case either x or previous is declared to throw an exception,
                 make sure both exception specifications are equal.  */
                 make sure both exception specifications are equal.  */
              if (decls_match (x, previous))
              if (decls_match (x, previous))
                {
                {
                  tree x_exception_spec = NULL_TREE;
                  tree x_exception_spec = NULL_TREE;
                  tree previous_exception_spec = NULL_TREE;
                  tree previous_exception_spec = NULL_TREE;
 
 
                  x_exception_spec =
                  x_exception_spec =
                                TYPE_RAISES_EXCEPTIONS (TREE_TYPE (x));
                                TYPE_RAISES_EXCEPTIONS (TREE_TYPE (x));
                  previous_exception_spec =
                  previous_exception_spec =
                                TYPE_RAISES_EXCEPTIONS (TREE_TYPE (previous));
                                TYPE_RAISES_EXCEPTIONS (TREE_TYPE (previous));
                  if (!comp_except_specs (previous_exception_spec,
                  if (!comp_except_specs (previous_exception_spec,
                                          x_exception_spec,
                                          x_exception_spec,
                                          true))
                                          true))
                    {
                    {
                      pedwarn (input_location, 0, "declaration of %q#D with C language linkage",
                      pedwarn (input_location, 0, "declaration of %q#D with C language linkage",
                               x);
                               x);
                      pedwarn (input_location, 0, "conflicts with previous declaration %q+#D",
                      pedwarn (input_location, 0, "conflicts with previous declaration %q+#D",
                               previous);
                               previous);
                      pedwarn (input_location, 0, "due to different exception specifications");
                      pedwarn (input_location, 0, "due to different exception specifications");
                      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
                      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
                    }
                    }
                }
                }
              else
              else
                {
                {
                  pedwarn (input_location, 0,
                  pedwarn (input_location, 0,
                           "declaration of %q#D with C language linkage", x);
                           "declaration of %q#D with C language linkage", x);
                  pedwarn (input_location, 0,
                  pedwarn (input_location, 0,
                           "conflicts with previous declaration %q+#D",
                           "conflicts with previous declaration %q+#D",
                           previous);
                           previous);
                }
                }
            }
            }
        }
        }
 
 
      check_template_shadow (x);
      check_template_shadow (x);
 
 
      /* If this is a function conjured up by the back end, massage it
      /* If this is a function conjured up by the back end, massage it
         so it looks friendly.  */
         so it looks friendly.  */
      if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_LANG_SPECIFIC (x))
      if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_LANG_SPECIFIC (x))
        {
        {
          retrofit_lang_decl (x);
          retrofit_lang_decl (x);
          SET_DECL_LANGUAGE (x, lang_c);
          SET_DECL_LANGUAGE (x, lang_c);
        }
        }
 
 
      t = x;
      t = x;
      if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_FUNCTION_MEMBER_P (x))
      if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_FUNCTION_MEMBER_P (x))
        {
        {
          t = push_overloaded_decl (x, PUSH_LOCAL, is_friend);
          t = push_overloaded_decl (x, PUSH_LOCAL, is_friend);
          if (!namespace_bindings_p ())
          if (!namespace_bindings_p ())
            /* We do not need to create a binding for this name;
            /* We do not need to create a binding for this name;
               push_overloaded_decl will have already done so if
               push_overloaded_decl will have already done so if
               necessary.  */
               necessary.  */
            need_new_binding = 0;
            need_new_binding = 0;
        }
        }
      else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
      else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
        {
        {
          t = push_overloaded_decl (x, PUSH_GLOBAL, is_friend);
          t = push_overloaded_decl (x, PUSH_GLOBAL, is_friend);
          if (t == x)
          if (t == x)
            add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
            add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
        }
        }
 
 
      if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
      if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
        check_default_args (t);
        check_default_args (t);
 
 
      if (t != x || DECL_FUNCTION_TEMPLATE_P (t))
      if (t != x || DECL_FUNCTION_TEMPLATE_P (t))
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
 
 
      /* If declaring a type as a typedef, copy the type (unless we're
      /* If declaring a type as a typedef, copy the type (unless we're
         at line 0), and install this TYPE_DECL as the new type's typedef
         at line 0), and install this TYPE_DECL as the new type's typedef
         name.  See the extensive comment of set_underlying_type ().  */
         name.  See the extensive comment of set_underlying_type ().  */
      if (TREE_CODE (x) == TYPE_DECL)
      if (TREE_CODE (x) == TYPE_DECL)
        {
        {
          tree type = TREE_TYPE (x);
          tree type = TREE_TYPE (x);
 
 
          if (DECL_IS_BUILTIN (x)
          if (DECL_IS_BUILTIN (x)
              || (TREE_TYPE (x) != error_mark_node
              || (TREE_TYPE (x) != error_mark_node
                  && TYPE_NAME (type) != x
                  && TYPE_NAME (type) != x
                  /* We don't want to copy the type when all we're
                  /* We don't want to copy the type when all we're
                     doing is making a TYPE_DECL for the purposes of
                     doing is making a TYPE_DECL for the purposes of
                     inlining.  */
                     inlining.  */
                  && (!TYPE_NAME (type)
                  && (!TYPE_NAME (type)
                      || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x))))
                      || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x))))
            cp_set_underlying_type (x);
            cp_set_underlying_type (x);
 
 
          if (type != error_mark_node
          if (type != error_mark_node
              && TYPE_NAME (type)
              && TYPE_NAME (type)
              && TYPE_IDENTIFIER (type))
              && TYPE_IDENTIFIER (type))
            set_identifier_type_value (DECL_NAME (x), x);
            set_identifier_type_value (DECL_NAME (x), x);
        }
        }
 
 
      /* Multiple external decls of the same identifier ought to match.
      /* Multiple external decls of the same identifier ought to match.
 
 
         We get warnings about inline functions where they are defined.
         We get warnings about inline functions where they are defined.
         We get warnings about other functions from push_overloaded_decl.
         We get warnings about other functions from push_overloaded_decl.
 
 
         Avoid duplicate warnings where they are used.  */
         Avoid duplicate warnings where they are used.  */
      if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL)
      if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL)
        {
        {
          tree decl;
          tree decl;
 
 
          decl = IDENTIFIER_NAMESPACE_VALUE (name);
          decl = IDENTIFIER_NAMESPACE_VALUE (name);
          if (decl && TREE_CODE (decl) == OVERLOAD)
          if (decl && TREE_CODE (decl) == OVERLOAD)
            decl = OVL_FUNCTION (decl);
            decl = OVL_FUNCTION (decl);
 
 
          if (decl && decl != error_mark_node
          if (decl && decl != error_mark_node
              && (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl))
              && (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl))
              /* If different sort of thing, we already gave an error.  */
              /* If different sort of thing, we already gave an error.  */
              && TREE_CODE (decl) == TREE_CODE (x)
              && TREE_CODE (decl) == TREE_CODE (x)
              && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl)))
              && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl)))
            {
            {
              permerror (input_location, "type mismatch with previous external decl of %q#D", x);
              permerror (input_location, "type mismatch with previous external decl of %q#D", x);
              permerror (input_location, "previous external decl of %q+#D", decl);
              permerror (input_location, "previous external decl of %q+#D", decl);
            }
            }
        }
        }
 
 
      if (TREE_CODE (x) == FUNCTION_DECL
      if (TREE_CODE (x) == FUNCTION_DECL
          && is_friend
          && is_friend
          && !flag_friend_injection)
          && !flag_friend_injection)
        {
        {
          /* This is a new declaration of a friend function, so hide
          /* This is a new declaration of a friend function, so hide
             it from ordinary function lookup.  */
             it from ordinary function lookup.  */
          DECL_ANTICIPATED (x) = 1;
          DECL_ANTICIPATED (x) = 1;
          DECL_HIDDEN_FRIEND_P (x) = 1;
          DECL_HIDDEN_FRIEND_P (x) = 1;
        }
        }
 
 
      /* This name is new in its binding level.
      /* This name is new in its binding level.
         Install the new declaration and return it.  */
         Install the new declaration and return it.  */
      if (namespace_bindings_p ())
      if (namespace_bindings_p ())
        {
        {
          /* Install a global value.  */
          /* Install a global value.  */
 
 
          /* If the first global decl has external linkage,
          /* If the first global decl has external linkage,
             warn if we later see static one.  */
             warn if we later see static one.  */
          if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
          if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
            TREE_PUBLIC (name) = 1;
            TREE_PUBLIC (name) = 1;
 
 
          /* Bind the name for the entity.  */
          /* Bind the name for the entity.  */
          if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
          if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
                && t != NULL_TREE)
                && t != NULL_TREE)
              && (TREE_CODE (x) == TYPE_DECL
              && (TREE_CODE (x) == TYPE_DECL
                  || TREE_CODE (x) == VAR_DECL
                  || TREE_CODE (x) == VAR_DECL
                  || TREE_CODE (x) == NAMESPACE_DECL
                  || TREE_CODE (x) == NAMESPACE_DECL
                  || TREE_CODE (x) == CONST_DECL
                  || TREE_CODE (x) == CONST_DECL
                  || TREE_CODE (x) == TEMPLATE_DECL))
                  || TREE_CODE (x) == TEMPLATE_DECL))
            SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
            SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
 
 
          /* If new decl is `static' and an `extern' was seen previously,
          /* If new decl is `static' and an `extern' was seen previously,
             warn about it.  */
             warn about it.  */
          if (x != NULL_TREE && t != NULL_TREE && decls_match (x, t))
          if (x != NULL_TREE && t != NULL_TREE && decls_match (x, t))
            warn_extern_redeclared_static (x, t);
            warn_extern_redeclared_static (x, t);
        }
        }
      else
      else
        {
        {
          /* Here to install a non-global value.  */
          /* Here to install a non-global value.  */
          tree oldlocal = innermost_non_namespace_value (name);
          tree oldlocal = innermost_non_namespace_value (name);
          tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
          tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
 
 
          if (need_new_binding)
          if (need_new_binding)
            {
            {
              push_local_binding (name, x, 0);
              push_local_binding (name, x, 0);
              /* Because push_local_binding will hook X on to the
              /* Because push_local_binding will hook X on to the
                 current_binding_level's name list, we don't want to
                 current_binding_level's name list, we don't want to
                 do that again below.  */
                 do that again below.  */
              need_new_binding = 0;
              need_new_binding = 0;
            }
            }
 
 
          /* If this is a TYPE_DECL, push it into the type value slot.  */
          /* If this is a TYPE_DECL, push it into the type value slot.  */
          if (TREE_CODE (x) == TYPE_DECL)
          if (TREE_CODE (x) == TYPE_DECL)
            set_identifier_type_value (name, x);
            set_identifier_type_value (name, x);
 
 
          /* Clear out any TYPE_DECL shadowed by a namespace so that
          /* Clear out any TYPE_DECL shadowed by a namespace so that
             we won't think this is a type.  The C struct hack doesn't
             we won't think this is a type.  The C struct hack doesn't
             go through namespaces.  */
             go through namespaces.  */
          if (TREE_CODE (x) == NAMESPACE_DECL)
          if (TREE_CODE (x) == NAMESPACE_DECL)
            set_identifier_type_value (name, NULL_TREE);
            set_identifier_type_value (name, NULL_TREE);
 
 
          if (oldlocal)
          if (oldlocal)
            {
            {
              tree d = oldlocal;
              tree d = oldlocal;
 
 
              while (oldlocal
              while (oldlocal
                     && TREE_CODE (oldlocal) == VAR_DECL
                     && TREE_CODE (oldlocal) == VAR_DECL
                     && DECL_DEAD_FOR_LOCAL (oldlocal))
                     && DECL_DEAD_FOR_LOCAL (oldlocal))
                oldlocal = DECL_SHADOWED_FOR_VAR (oldlocal);
                oldlocal = DECL_SHADOWED_FOR_VAR (oldlocal);
 
 
              if (oldlocal == NULL_TREE)
              if (oldlocal == NULL_TREE)
                oldlocal = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (d));
                oldlocal = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (d));
            }
            }
 
 
          /* If this is an extern function declaration, see if we
          /* If this is an extern function declaration, see if we
             have a global definition or declaration for the function.  */
             have a global definition or declaration for the function.  */
          if (oldlocal == NULL_TREE
          if (oldlocal == NULL_TREE
              && DECL_EXTERNAL (x)
              && DECL_EXTERNAL (x)
              && oldglobal != NULL_TREE
              && oldglobal != NULL_TREE
              && TREE_CODE (x) == FUNCTION_DECL
              && TREE_CODE (x) == FUNCTION_DECL
              && TREE_CODE (oldglobal) == FUNCTION_DECL)
              && TREE_CODE (oldglobal) == FUNCTION_DECL)
            {
            {
              /* We have one.  Their types must agree.  */
              /* We have one.  Their types must agree.  */
              if (decls_match (x, oldglobal))
              if (decls_match (x, oldglobal))
                /* OK */;
                /* OK */;
              else
              else
                {
                {
                  warning (0, "extern declaration of %q#D doesn't match", x);
                  warning (0, "extern declaration of %q#D doesn't match", x);
                  warning (0, "global declaration %q+#D", oldglobal);
                  warning (0, "global declaration %q+#D", oldglobal);
                }
                }
            }
            }
          /* If we have a local external declaration,
          /* If we have a local external declaration,
             and no file-scope declaration has yet been seen,
             and no file-scope declaration has yet been seen,
             then if we later have a file-scope decl it must not be static.  */
             then if we later have a file-scope decl it must not be static.  */
          if (oldlocal == NULL_TREE
          if (oldlocal == NULL_TREE
              && oldglobal == NULL_TREE
              && oldglobal == NULL_TREE
              && DECL_EXTERNAL (x)
              && DECL_EXTERNAL (x)
              && TREE_PUBLIC (x))
              && TREE_PUBLIC (x))
            TREE_PUBLIC (name) = 1;
            TREE_PUBLIC (name) = 1;
 
 
          /* Don't complain about the parms we push and then pop
          /* Don't complain about the parms we push and then pop
             while tentatively parsing a function declarator.  */
             while tentatively parsing a function declarator.  */
          if (TREE_CODE (x) == PARM_DECL && DECL_CONTEXT (x) == NULL_TREE)
          if (TREE_CODE (x) == PARM_DECL && DECL_CONTEXT (x) == NULL_TREE)
            /* Ignore.  */;
            /* Ignore.  */;
 
 
          /* Warn if shadowing an argument at the top level of the body.  */
          /* Warn if shadowing an argument at the top level of the body.  */
          else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
          else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
                   /* Inline decls shadow nothing.  */
                   /* Inline decls shadow nothing.  */
                   && !DECL_FROM_INLINE (x)
                   && !DECL_FROM_INLINE (x)
                   && TREE_CODE (oldlocal) == PARM_DECL
                   && TREE_CODE (oldlocal) == PARM_DECL
                   /* Don't check the `this' parameter.  */
                   /* Don't check the `this' parameter.  */
                   && !DECL_ARTIFICIAL (oldlocal))
                   && !DECL_ARTIFICIAL (oldlocal))
            {
            {
              bool err = false;
              bool err = false;
 
 
              /* Don't complain if it's from an enclosing function.  */
              /* Don't complain if it's from an enclosing function.  */
              if (DECL_CONTEXT (oldlocal) == current_function_decl
              if (DECL_CONTEXT (oldlocal) == current_function_decl
                  && TREE_CODE (x) != PARM_DECL)
                  && TREE_CODE (x) != PARM_DECL)
                {
                {
                  /* Go to where the parms should be and see if we find
                  /* Go to where the parms should be and see if we find
                     them there.  */
                     them there.  */
                  struct cp_binding_level *b = current_binding_level->level_chain;
                  struct cp_binding_level *b = current_binding_level->level_chain;
 
 
                  if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
                  if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
                    /* Skip the ctor/dtor cleanup level.  */
                    /* Skip the ctor/dtor cleanup level.  */
                    b = b->level_chain;
                    b = b->level_chain;
 
 
                  /* ARM $8.3 */
                  /* ARM $8.3 */
                  if (b->kind == sk_function_parms)
                  if (b->kind == sk_function_parms)
                    {
                    {
                      error ("declaration of %q#D shadows a parameter", x);
                      error ("declaration of %q#D shadows a parameter", x);
                      err = true;
                      err = true;
                    }
                    }
                }
                }
 
 
              if (warn_shadow && !err)
              if (warn_shadow && !err)
                {
                {
                  warning_at (input_location, OPT_Wshadow,
                  warning_at (input_location, OPT_Wshadow,
                              "declaration of %q#D shadows a parameter", x);
                              "declaration of %q#D shadows a parameter", x);
                  warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
                  warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
                              "shadowed declaration is here");
                              "shadowed declaration is here");
                }
                }
            }
            }
 
 
          /* Maybe warn if shadowing something else.  */
          /* Maybe warn if shadowing something else.  */
          else if (warn_shadow && !DECL_EXTERNAL (x)
          else if (warn_shadow && !DECL_EXTERNAL (x)
              /* No shadow warnings for internally generated vars.  */
              /* No shadow warnings for internally generated vars.  */
              && ! DECL_ARTIFICIAL (x)
              && ! DECL_ARTIFICIAL (x)
              /* No shadow warnings for vars made for inlining.  */
              /* No shadow warnings for vars made for inlining.  */
              && ! DECL_FROM_INLINE (x))
              && ! DECL_FROM_INLINE (x))
            {
            {
              tree member;
              tree member;
 
 
              if (current_class_ptr)
              if (current_class_ptr)
                member = lookup_member (current_class_type,
                member = lookup_member (current_class_type,
                                        name,
                                        name,
                                        /*protect=*/0,
                                        /*protect=*/0,
                                        /*want_type=*/false);
                                        /*want_type=*/false);
              else
              else
                member = NULL_TREE;
                member = NULL_TREE;
 
 
              if (member && !TREE_STATIC (member))
              if (member && !TREE_STATIC (member))
                {
                {
                  /* Location of previous decl is not useful in this case.  */
                  /* Location of previous decl is not useful in this case.  */
                  warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'",
                  warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'",
                           x);
                           x);
                }
                }
              else if (oldlocal != NULL_TREE
              else if (oldlocal != NULL_TREE
                       && TREE_CODE (oldlocal) == VAR_DECL)
                       && TREE_CODE (oldlocal) == VAR_DECL)
                {
                {
                  warning_at (input_location, OPT_Wshadow,
                  warning_at (input_location, OPT_Wshadow,
                              "declaration of %qD shadows a previous local", x);
                              "declaration of %qD shadows a previous local", x);
                  warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
                  warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
                              "shadowed declaration is here");
                              "shadowed declaration is here");
                }
                }
              else if (oldglobal != NULL_TREE
              else if (oldglobal != NULL_TREE
                       && TREE_CODE (oldglobal) == VAR_DECL)
                       && TREE_CODE (oldglobal) == VAR_DECL)
                /* XXX shadow warnings in outer-more namespaces */
                /* XXX shadow warnings in outer-more namespaces */
                {
                {
                  warning_at (input_location, OPT_Wshadow,
                  warning_at (input_location, OPT_Wshadow,
                              "declaration of %qD shadows a global declaration", x);
                              "declaration of %qD shadows a global declaration", x);
                  warning_at (DECL_SOURCE_LOCATION (oldglobal), OPT_Wshadow,
                  warning_at (DECL_SOURCE_LOCATION (oldglobal), OPT_Wshadow,
                              "shadowed declaration is here");
                              "shadowed declaration is here");
                }
                }
            }
            }
        }
        }
 
 
      if (TREE_CODE (x) == VAR_DECL)
      if (TREE_CODE (x) == VAR_DECL)
        maybe_register_incomplete_var (x);
        maybe_register_incomplete_var (x);
    }
    }
 
 
  if (need_new_binding)
  if (need_new_binding)
    add_decl_to_level (x,
    add_decl_to_level (x,
                       DECL_NAMESPACE_SCOPE_P (x)
                       DECL_NAMESPACE_SCOPE_P (x)
                       ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
                       ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
                       : current_binding_level);
                       : current_binding_level);
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
}
}
 
 
/* Record a decl-node X as belonging to the current lexical scope.  */
/* Record a decl-node X as belonging to the current lexical scope.  */
 
 
tree
tree
pushdecl (tree x)
pushdecl (tree x)
{
{
  return pushdecl_maybe_friend (x, false);
  return pushdecl_maybe_friend (x, false);
}
}
 
 
/* Enter DECL into the symbol table, if that's appropriate.  Returns
/* Enter DECL into the symbol table, if that's appropriate.  Returns
   DECL, or a modified version thereof.  */
   DECL, or a modified version thereof.  */
 
 
tree
tree
maybe_push_decl (tree decl)
maybe_push_decl (tree decl)
{
{
  tree type = TREE_TYPE (decl);
  tree type = TREE_TYPE (decl);
 
 
  /* Add this decl to the current binding level, but not if it comes
  /* Add this decl to the current binding level, but not if it comes
     from another scope, e.g. a static member variable.  TEM may equal
     from another scope, e.g. a static member variable.  TEM may equal
     DECL or it may be a previous decl of the same name.  */
     DECL or it may be a previous decl of the same name.  */
  if (decl == error_mark_node
  if (decl == error_mark_node
      || (TREE_CODE (decl) != PARM_DECL
      || (TREE_CODE (decl) != PARM_DECL
          && DECL_CONTEXT (decl) != NULL_TREE
          && DECL_CONTEXT (decl) != NULL_TREE
          /* Definitions of namespace members outside their namespace are
          /* Definitions of namespace members outside their namespace are
             possible.  */
             possible.  */
          && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
          && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
      || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
      || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
      || TREE_CODE (type) == UNKNOWN_TYPE
      || TREE_CODE (type) == UNKNOWN_TYPE
      /* The declaration of a template specialization does not affect
      /* The declaration of a template specialization does not affect
         the functions available for overload resolution, so we do not
         the functions available for overload resolution, so we do not
         call pushdecl.  */
         call pushdecl.  */
      || (TREE_CODE (decl) == FUNCTION_DECL
      || (TREE_CODE (decl) == FUNCTION_DECL
          && DECL_TEMPLATE_SPECIALIZATION (decl)))
          && DECL_TEMPLATE_SPECIALIZATION (decl)))
    return decl;
    return decl;
  else
  else
    return pushdecl (decl);
    return pushdecl (decl);
}
}
 
 
/* Bind DECL to ID in the current_binding_level, assumed to be a local
/* Bind DECL to ID in the current_binding_level, assumed to be a local
   binding level.  If PUSH_USING is set in FLAGS, we know that DECL
   binding level.  If PUSH_USING is set in FLAGS, we know that DECL
   doesn't really belong to this binding level, that it got here
   doesn't really belong to this binding level, that it got here
   through a using-declaration.  */
   through a using-declaration.  */
 
 
void
void
push_local_binding (tree id, tree decl, int flags)
push_local_binding (tree id, tree decl, int flags)
{
{
  struct cp_binding_level *b;
  struct cp_binding_level *b;
 
 
  /* Skip over any local classes.  This makes sense if we call
  /* Skip over any local classes.  This makes sense if we call
     push_local_binding with a friend decl of a local class.  */
     push_local_binding with a friend decl of a local class.  */
  b = innermost_nonclass_level ();
  b = innermost_nonclass_level ();
 
 
  if (lookup_name_innermost_nonclass_level (id))
  if (lookup_name_innermost_nonclass_level (id))
    {
    {
      /* Supplement the existing binding.  */
      /* Supplement the existing binding.  */
      if (!supplement_binding (IDENTIFIER_BINDING (id), decl))
      if (!supplement_binding (IDENTIFIER_BINDING (id), decl))
        /* It didn't work.  Something else must be bound at this
        /* It didn't work.  Something else must be bound at this
           level.  Do not add DECL to the list of things to pop
           level.  Do not add DECL to the list of things to pop
           later.  */
           later.  */
        return;
        return;
    }
    }
  else
  else
    /* Create a new binding.  */
    /* Create a new binding.  */
    push_binding (id, decl, b);
    push_binding (id, decl, b);
 
 
  if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING))
  if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING))
    /* We must put the OVERLOAD into a TREE_LIST since the
    /* We must put the OVERLOAD into a TREE_LIST since the
       TREE_CHAIN of an OVERLOAD is already used.  Similarly for
       TREE_CHAIN of an OVERLOAD is already used.  Similarly for
       decls that got here through a using-declaration.  */
       decls that got here through a using-declaration.  */
    decl = build_tree_list (NULL_TREE, decl);
    decl = build_tree_list (NULL_TREE, decl);
 
 
  /* And put DECL on the list of things declared by the current
  /* And put DECL on the list of things declared by the current
     binding level.  */
     binding level.  */
  add_decl_to_level (decl, b);
  add_decl_to_level (decl, b);
}
}
 
 
/* Check to see whether or not DECL is a variable that would have been
/* Check to see whether or not DECL is a variable that would have been
   in scope under the ARM, but is not in scope under the ANSI/ISO
   in scope under the ARM, but is not in scope under the ANSI/ISO
   standard.  If so, issue an error message.  If name lookup would
   standard.  If so, issue an error message.  If name lookup would
   work in both cases, but return a different result, this function
   work in both cases, but return a different result, this function
   returns the result of ANSI/ISO lookup.  Otherwise, it returns
   returns the result of ANSI/ISO lookup.  Otherwise, it returns
   DECL.  */
   DECL.  */
 
 
tree
tree
check_for_out_of_scope_variable (tree decl)
check_for_out_of_scope_variable (tree decl)
{
{
  tree shadowed;
  tree shadowed;
 
 
  /* We only care about out of scope variables.  */
  /* We only care about out of scope variables.  */
  if (!(TREE_CODE (decl) == VAR_DECL && DECL_DEAD_FOR_LOCAL (decl)))
  if (!(TREE_CODE (decl) == VAR_DECL && DECL_DEAD_FOR_LOCAL (decl)))
    return decl;
    return decl;
 
 
  shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (decl)
  shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (decl)
    ? DECL_SHADOWED_FOR_VAR (decl) : NULL_TREE ;
    ? DECL_SHADOWED_FOR_VAR (decl) : NULL_TREE ;
  while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
  while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
         && DECL_DEAD_FOR_LOCAL (shadowed))
         && DECL_DEAD_FOR_LOCAL (shadowed))
    shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (shadowed)
    shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (shadowed)
      ? DECL_SHADOWED_FOR_VAR (shadowed) : NULL_TREE;
      ? DECL_SHADOWED_FOR_VAR (shadowed) : NULL_TREE;
  if (!shadowed)
  if (!shadowed)
    shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (decl));
    shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (decl));
  if (shadowed)
  if (shadowed)
    {
    {
      if (!DECL_ERROR_REPORTED (decl))
      if (!DECL_ERROR_REPORTED (decl))
        {
        {
          warning (0, "name lookup of %qD changed", DECL_NAME (decl));
          warning (0, "name lookup of %qD changed", DECL_NAME (decl));
          warning (0, "  matches this %q+D under ISO standard rules",
          warning (0, "  matches this %q+D under ISO standard rules",
                   shadowed);
                   shadowed);
          warning (0, "  matches this %q+D under old rules", decl);
          warning (0, "  matches this %q+D under old rules", decl);
          DECL_ERROR_REPORTED (decl) = 1;
          DECL_ERROR_REPORTED (decl) = 1;
        }
        }
      return shadowed;
      return shadowed;
    }
    }
 
 
  /* If we have already complained about this declaration, there's no
  /* If we have already complained about this declaration, there's no
     need to do it again.  */
     need to do it again.  */
  if (DECL_ERROR_REPORTED (decl))
  if (DECL_ERROR_REPORTED (decl))
    return decl;
    return decl;
 
 
  DECL_ERROR_REPORTED (decl) = 1;
  DECL_ERROR_REPORTED (decl) = 1;
 
 
  if (TREE_TYPE (decl) == error_mark_node)
  if (TREE_TYPE (decl) == error_mark_node)
    return decl;
    return decl;
 
 
  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
    {
    {
      error ("name lookup of %qD changed for ISO %<for%> scoping",
      error ("name lookup of %qD changed for ISO %<for%> scoping",
             DECL_NAME (decl));
             DECL_NAME (decl));
      error ("  cannot use obsolete binding at %q+D because "
      error ("  cannot use obsolete binding at %q+D because "
             "it has a destructor", decl);
             "it has a destructor", decl);
      return error_mark_node;
      return error_mark_node;
    }
    }
  else
  else
    {
    {
      permerror (input_location, "name lookup of %qD changed for ISO %<for%> scoping",
      permerror (input_location, "name lookup of %qD changed for ISO %<for%> scoping",
                 DECL_NAME (decl));
                 DECL_NAME (decl));
      if (flag_permissive)
      if (flag_permissive)
        permerror (input_location, "  using obsolete binding at %q+D", decl);
        permerror (input_location, "  using obsolete binding at %q+D", decl);
      else
      else
        {
        {
          static bool hint;
          static bool hint;
          if (!hint)
          if (!hint)
            {
            {
              inform (input_location, "(if you use %<-fpermissive%> G++ will accept your code)");
              inform (input_location, "(if you use %<-fpermissive%> G++ will accept your code)");
              hint = true;
              hint = true;
            }
            }
        }
        }
    }
    }
 
 
  return decl;
  return decl;
}
}


/* true means unconditionally make a BLOCK for the next level pushed.  */
/* true means unconditionally make a BLOCK for the next level pushed.  */
 
 
static bool keep_next_level_flag;
static bool keep_next_level_flag;
 
 
static int binding_depth = 0;
static int binding_depth = 0;
 
 
static void
static void
indent (int depth)
indent (int depth)
{
{
  int i;
  int i;
 
 
  for (i = 0; i < depth * 2; i++)
  for (i = 0; i < depth * 2; i++)
    putc (' ', stderr);
    putc (' ', stderr);
}
}
 
 
/* Return a string describing the kind of SCOPE we have.  */
/* Return a string describing the kind of SCOPE we have.  */
static const char *
static const char *
cxx_scope_descriptor (cxx_scope *scope)
cxx_scope_descriptor (cxx_scope *scope)
{
{
  /* The order of this table must match the "scope_kind"
  /* The order of this table must match the "scope_kind"
     enumerators.  */
     enumerators.  */
  static const char* scope_kind_names[] = {
  static const char* scope_kind_names[] = {
    "block-scope",
    "block-scope",
    "cleanup-scope",
    "cleanup-scope",
    "try-scope",
    "try-scope",
    "catch-scope",
    "catch-scope",
    "for-scope",
    "for-scope",
    "function-parameter-scope",
    "function-parameter-scope",
    "class-scope",
    "class-scope",
    "namespace-scope",
    "namespace-scope",
    "template-parameter-scope",
    "template-parameter-scope",
    "template-explicit-spec-scope"
    "template-explicit-spec-scope"
  };
  };
  const scope_kind kind = scope->explicit_spec_p
  const scope_kind kind = scope->explicit_spec_p
    ? sk_template_spec : scope->kind;
    ? sk_template_spec : scope->kind;
 
 
  return scope_kind_names[kind];
  return scope_kind_names[kind];
}
}
 
 
/* Output a debugging information about SCOPE when performing
/* Output a debugging information about SCOPE when performing
   ACTION at LINE.  */
   ACTION at LINE.  */
static void
static void
cxx_scope_debug (cxx_scope *scope, int line, const char *action)
cxx_scope_debug (cxx_scope *scope, int line, const char *action)
{
{
  const char *desc = cxx_scope_descriptor (scope);
  const char *desc = cxx_scope_descriptor (scope);
  if (scope->this_entity)
  if (scope->this_entity)
    verbatim ("%s %s(%E) %p %d\n", action, desc,
    verbatim ("%s %s(%E) %p %d\n", action, desc,
              scope->this_entity, (void *) scope, line);
              scope->this_entity, (void *) scope, line);
  else
  else
    verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line);
    verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line);
}
}
 
 
/* Return the estimated initial size of the hashtable of a NAMESPACE
/* Return the estimated initial size of the hashtable of a NAMESPACE
   scope.  */
   scope.  */
 
 
static inline size_t
static inline size_t
namespace_scope_ht_size (tree ns)
namespace_scope_ht_size (tree ns)
{
{
  tree name = DECL_NAME (ns);
  tree name = DECL_NAME (ns);
 
 
  return name == std_identifier
  return name == std_identifier
    ? NAMESPACE_STD_HT_SIZE
    ? NAMESPACE_STD_HT_SIZE
    : (name == global_scope_name
    : (name == global_scope_name
       ? GLOBAL_SCOPE_HT_SIZE
       ? GLOBAL_SCOPE_HT_SIZE
       : NAMESPACE_ORDINARY_HT_SIZE);
       : NAMESPACE_ORDINARY_HT_SIZE);
}
}
 
 
/* A chain of binding_level structures awaiting reuse.  */
/* A chain of binding_level structures awaiting reuse.  */
 
 
static GTY((deletable)) struct cp_binding_level *free_binding_level;
static GTY((deletable)) struct cp_binding_level *free_binding_level;
 
 
/* Insert SCOPE as the innermost binding level.  */
/* Insert SCOPE as the innermost binding level.  */
 
 
void
void
push_binding_level (struct cp_binding_level *scope)
push_binding_level (struct cp_binding_level *scope)
{
{
  /* Add it to the front of currently active scopes stack.  */
  /* Add it to the front of currently active scopes stack.  */
  scope->level_chain = current_binding_level;
  scope->level_chain = current_binding_level;
  current_binding_level = scope;
  current_binding_level = scope;
  keep_next_level_flag = false;
  keep_next_level_flag = false;
 
 
  if (ENABLE_SCOPE_CHECKING)
  if (ENABLE_SCOPE_CHECKING)
    {
    {
      scope->binding_depth = binding_depth;
      scope->binding_depth = binding_depth;
      indent (binding_depth);
      indent (binding_depth);
      cxx_scope_debug (scope, input_line, "push");
      cxx_scope_debug (scope, input_line, "push");
      binding_depth++;
      binding_depth++;
    }
    }
}
}
 
 
/* Create a new KIND scope and make it the top of the active scopes stack.
/* Create a new KIND scope and make it the top of the active scopes stack.
   ENTITY is the scope of the associated C++ entity (namespace, class,
   ENTITY is the scope of the associated C++ entity (namespace, class,
   function, C++0x enumeration); it is NULL otherwise.  */
   function, C++0x enumeration); it is NULL otherwise.  */
 
 
cxx_scope *
cxx_scope *
begin_scope (scope_kind kind, tree entity)
begin_scope (scope_kind kind, tree entity)
{
{
  cxx_scope *scope;
  cxx_scope *scope;
 
 
  /* Reuse or create a struct for this binding level.  */
  /* Reuse or create a struct for this binding level.  */
  if (!ENABLE_SCOPE_CHECKING && free_binding_level)
  if (!ENABLE_SCOPE_CHECKING && free_binding_level)
    {
    {
      scope = free_binding_level;
      scope = free_binding_level;
      memset (scope, 0, sizeof (cxx_scope));
      memset (scope, 0, sizeof (cxx_scope));
      free_binding_level = scope->level_chain;
      free_binding_level = scope->level_chain;
    }
    }
  else
  else
    scope = GGC_CNEW (cxx_scope);
    scope = GGC_CNEW (cxx_scope);
 
 
  scope->this_entity = entity;
  scope->this_entity = entity;
  scope->more_cleanups_ok = true;
  scope->more_cleanups_ok = true;
  switch (kind)
  switch (kind)
    {
    {
    case sk_cleanup:
    case sk_cleanup:
      scope->keep = true;
      scope->keep = true;
      break;
      break;
 
 
    case sk_template_spec:
    case sk_template_spec:
      scope->explicit_spec_p = true;
      scope->explicit_spec_p = true;
      kind = sk_template_parms;
      kind = sk_template_parms;
      /* Fall through.  */
      /* Fall through.  */
    case sk_template_parms:
    case sk_template_parms:
    case sk_block:
    case sk_block:
    case sk_try:
    case sk_try:
    case sk_catch:
    case sk_catch:
    case sk_for:
    case sk_for:
    case sk_class:
    case sk_class:
    case sk_scoped_enum:
    case sk_scoped_enum:
    case sk_function_parms:
    case sk_function_parms:
    case sk_omp:
    case sk_omp:
      scope->keep = keep_next_level_flag;
      scope->keep = keep_next_level_flag;
      break;
      break;
 
 
    case sk_namespace:
    case sk_namespace:
      NAMESPACE_LEVEL (entity) = scope;
      NAMESPACE_LEVEL (entity) = scope;
      scope->static_decls =
      scope->static_decls =
        VEC_alloc (tree, gc,
        VEC_alloc (tree, gc,
                   DECL_NAME (entity) == std_identifier
                   DECL_NAME (entity) == std_identifier
                   || DECL_NAME (entity) == global_scope_name
                   || DECL_NAME (entity) == global_scope_name
                   ? 200 : 10);
                   ? 200 : 10);
      break;
      break;
 
 
    default:
    default:
      /* Should not happen.  */
      /* Should not happen.  */
      gcc_unreachable ();
      gcc_unreachable ();
      break;
      break;
    }
    }
  scope->kind = kind;
  scope->kind = kind;
 
 
  push_binding_level (scope);
  push_binding_level (scope);
 
 
  return scope;
  return scope;
}
}
 
 
/* We're about to leave current scope.  Pop the top of the stack of
/* We're about to leave current scope.  Pop the top of the stack of
   currently active scopes.  Return the enclosing scope, now active.  */
   currently active scopes.  Return the enclosing scope, now active.  */
 
 
cxx_scope *
cxx_scope *
leave_scope (void)
leave_scope (void)
{
{
  cxx_scope *scope = current_binding_level;
  cxx_scope *scope = current_binding_level;
 
 
  if (scope->kind == sk_namespace && class_binding_level)
  if (scope->kind == sk_namespace && class_binding_level)
    current_binding_level = class_binding_level;
    current_binding_level = class_binding_level;
 
 
  /* We cannot leave a scope, if there are none left.  */
  /* We cannot leave a scope, if there are none left.  */
  if (NAMESPACE_LEVEL (global_namespace))
  if (NAMESPACE_LEVEL (global_namespace))
    gcc_assert (!global_scope_p (scope));
    gcc_assert (!global_scope_p (scope));
 
 
  if (ENABLE_SCOPE_CHECKING)
  if (ENABLE_SCOPE_CHECKING)
    {
    {
      indent (--binding_depth);
      indent (--binding_depth);
      cxx_scope_debug (scope, input_line, "leave");
      cxx_scope_debug (scope, input_line, "leave");
    }
    }
 
 
  /* Move one nesting level up.  */
  /* Move one nesting level up.  */
  current_binding_level = scope->level_chain;
  current_binding_level = scope->level_chain;
 
 
  /* Namespace-scopes are left most probably temporarily, not
  /* Namespace-scopes are left most probably temporarily, not
     completely; they can be reopened later, e.g. in namespace-extension
     completely; they can be reopened later, e.g. in namespace-extension
     or any name binding activity that requires us to resume a
     or any name binding activity that requires us to resume a
     namespace.  For classes, we cache some binding levels.  For other
     namespace.  For classes, we cache some binding levels.  For other
     scopes, we just make the structure available for reuse.  */
     scopes, we just make the structure available for reuse.  */
  if (scope->kind != sk_namespace
  if (scope->kind != sk_namespace
      && scope->kind != sk_class)
      && scope->kind != sk_class)
    {
    {
      scope->level_chain = free_binding_level;
      scope->level_chain = free_binding_level;
      gcc_assert (!ENABLE_SCOPE_CHECKING
      gcc_assert (!ENABLE_SCOPE_CHECKING
                  || scope->binding_depth == binding_depth);
                  || scope->binding_depth == binding_depth);
      free_binding_level = scope;
      free_binding_level = scope;
    }
    }
 
 
  /* Find the innermost enclosing class scope, and reset
  /* Find the innermost enclosing class scope, and reset
     CLASS_BINDING_LEVEL appropriately.  */
     CLASS_BINDING_LEVEL appropriately.  */
  if (scope->kind == sk_class)
  if (scope->kind == sk_class)
    {
    {
      class_binding_level = NULL;
      class_binding_level = NULL;
      for (scope = current_binding_level; scope; scope = scope->level_chain)
      for (scope = current_binding_level; scope; scope = scope->level_chain)
        if (scope->kind == sk_class)
        if (scope->kind == sk_class)
          {
          {
            class_binding_level = scope;
            class_binding_level = scope;
            break;
            break;
          }
          }
    }
    }
 
 
  return current_binding_level;
  return current_binding_level;
}
}
 
 
static void
static void
resume_scope (struct cp_binding_level* b)
resume_scope (struct cp_binding_level* b)
{
{
  /* Resuming binding levels is meant only for namespaces,
  /* Resuming binding levels is meant only for namespaces,
     and those cannot nest into classes.  */
     and those cannot nest into classes.  */
  gcc_assert (!class_binding_level);
  gcc_assert (!class_binding_level);
  /* Also, resuming a non-directly nested namespace is a no-no.  */
  /* Also, resuming a non-directly nested namespace is a no-no.  */
  gcc_assert (b->level_chain == current_binding_level);
  gcc_assert (b->level_chain == current_binding_level);
  current_binding_level = b;
  current_binding_level = b;
  if (ENABLE_SCOPE_CHECKING)
  if (ENABLE_SCOPE_CHECKING)
    {
    {
      b->binding_depth = binding_depth;
      b->binding_depth = binding_depth;
      indent (binding_depth);
      indent (binding_depth);
      cxx_scope_debug (b, input_line, "resume");
      cxx_scope_debug (b, input_line, "resume");
      binding_depth++;
      binding_depth++;
    }
    }
}
}
 
 
/* Return the innermost binding level that is not for a class scope.  */
/* Return the innermost binding level that is not for a class scope.  */
 
 
static cxx_scope *
static cxx_scope *
innermost_nonclass_level (void)
innermost_nonclass_level (void)
{
{
  cxx_scope *b;
  cxx_scope *b;
 
 
  b = current_binding_level;
  b = current_binding_level;
  while (b->kind == sk_class)
  while (b->kind == sk_class)
    b = b->level_chain;
    b = b->level_chain;
 
 
  return b;
  return b;
}
}
 
 
/* We're defining an object of type TYPE.  If it needs a cleanup, but
/* We're defining an object of type TYPE.  If it needs a cleanup, but
   we're not allowed to add any more objects with cleanups to the current
   we're not allowed to add any more objects with cleanups to the current
   scope, create a new binding level.  */
   scope, create a new binding level.  */
 
 
void
void
maybe_push_cleanup_level (tree type)
maybe_push_cleanup_level (tree type)
{
{
  if (type != error_mark_node
  if (type != error_mark_node
      && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
      && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
      && current_binding_level->more_cleanups_ok == 0)
      && current_binding_level->more_cleanups_ok == 0)
    {
    {
      begin_scope (sk_cleanup, NULL);
      begin_scope (sk_cleanup, NULL);
      current_binding_level->statement_list = push_stmt_list ();
      current_binding_level->statement_list = push_stmt_list ();
    }
    }
}
}
 
 
/* Nonzero if we are currently in the global binding level.  */
/* Nonzero if we are currently in the global binding level.  */
 
 
int
int
global_bindings_p (void)
global_bindings_p (void)
{
{
  return global_scope_p (current_binding_level);
  return global_scope_p (current_binding_level);
}
}
 
 
/* True if we are currently in a toplevel binding level.  This
/* True if we are currently in a toplevel binding level.  This
   means either the global binding level or a namespace in a toplevel
   means either the global binding level or a namespace in a toplevel
   binding level.  Since there are no non-toplevel namespace levels,
   binding level.  Since there are no non-toplevel namespace levels,
   this really means any namespace or template parameter level.  We
   this really means any namespace or template parameter level.  We
   also include a class whose context is toplevel.  */
   also include a class whose context is toplevel.  */
 
 
bool
bool
toplevel_bindings_p (void)
toplevel_bindings_p (void)
{
{
  struct cp_binding_level *b = innermost_nonclass_level ();
  struct cp_binding_level *b = innermost_nonclass_level ();
 
 
  return b->kind == sk_namespace || b->kind == sk_template_parms;
  return b->kind == sk_namespace || b->kind == sk_template_parms;
}
}
 
 
/* True if this is a namespace scope, or if we are defining a class
/* True if this is a namespace scope, or if we are defining a class
   which is itself at namespace scope, or whose enclosing class is
   which is itself at namespace scope, or whose enclosing class is
   such a class, etc.  */
   such a class, etc.  */
 
 
bool
bool
namespace_bindings_p (void)
namespace_bindings_p (void)
{
{
  struct cp_binding_level *b = innermost_nonclass_level ();
  struct cp_binding_level *b = innermost_nonclass_level ();
 
 
  return b->kind == sk_namespace;
  return b->kind == sk_namespace;
}
}
 
 
/* True if the current level needs to have a BLOCK made.  */
/* True if the current level needs to have a BLOCK made.  */
 
 
bool
bool
kept_level_p (void)
kept_level_p (void)
{
{
  return (current_binding_level->blocks != NULL_TREE
  return (current_binding_level->blocks != NULL_TREE
          || current_binding_level->keep
          || current_binding_level->keep
          || current_binding_level->kind == sk_cleanup
          || current_binding_level->kind == sk_cleanup
          || current_binding_level->names != NULL_TREE
          || current_binding_level->names != NULL_TREE
          || current_binding_level->using_directives);
          || current_binding_level->using_directives);
}
}
 
 
/* Returns the kind of the innermost scope.  */
/* Returns the kind of the innermost scope.  */
 
 
scope_kind
scope_kind
innermost_scope_kind (void)
innermost_scope_kind (void)
{
{
  return current_binding_level->kind;
  return current_binding_level->kind;
}
}
 
 
/* Returns true if this scope was created to store template parameters.  */
/* Returns true if this scope was created to store template parameters.  */
 
 
bool
bool
template_parm_scope_p (void)
template_parm_scope_p (void)
{
{
  return innermost_scope_kind () == sk_template_parms;
  return innermost_scope_kind () == sk_template_parms;
}
}
 
 
/* If KEEP is true, make a BLOCK node for the next binding level,
/* If KEEP is true, make a BLOCK node for the next binding level,
   unconditionally.  Otherwise, use the normal logic to decide whether
   unconditionally.  Otherwise, use the normal logic to decide whether
   or not to create a BLOCK.  */
   or not to create a BLOCK.  */
 
 
void
void
keep_next_level (bool keep)
keep_next_level (bool keep)
{
{
  keep_next_level_flag = keep;
  keep_next_level_flag = keep;
}
}
 
 
/* Return the list of declarations of the current level.
/* Return the list of declarations of the current level.
   Note that this list is in reverse order unless/until
   Note that this list is in reverse order unless/until
   you nreverse it; and when you do nreverse it, you must
   you nreverse it; and when you do nreverse it, you must
   store the result back using `storedecls' or you will lose.  */
   store the result back using `storedecls' or you will lose.  */
 
 
tree
tree
getdecls (void)
getdecls (void)
{
{
  return current_binding_level->names;
  return current_binding_level->names;
}
}
 
 
/* For debugging.  */
/* For debugging.  */
static int no_print_functions = 0;
static int no_print_functions = 0;
static int no_print_builtins = 0;
static int no_print_builtins = 0;
 
 
static void
static void
print_binding_level (struct cp_binding_level* lvl)
print_binding_level (struct cp_binding_level* lvl)
{
{
  tree t;
  tree t;
  int i = 0, len;
  int i = 0, len;
  fprintf (stderr, " blocks=%p", (void *) lvl->blocks);
  fprintf (stderr, " blocks=%p", (void *) lvl->blocks);
  if (lvl->more_cleanups_ok)
  if (lvl->more_cleanups_ok)
    fprintf (stderr, " more-cleanups-ok");
    fprintf (stderr, " more-cleanups-ok");
  if (lvl->have_cleanups)
  if (lvl->have_cleanups)
    fprintf (stderr, " have-cleanups");
    fprintf (stderr, " have-cleanups");
  fprintf (stderr, "\n");
  fprintf (stderr, "\n");
  if (lvl->names)
  if (lvl->names)
    {
    {
      fprintf (stderr, " names:\t");
      fprintf (stderr, " names:\t");
      /* We can probably fit 3 names to a line?  */
      /* We can probably fit 3 names to a line?  */
      for (t = lvl->names; t; t = TREE_CHAIN (t))
      for (t = lvl->names; t; t = TREE_CHAIN (t))
        {
        {
          if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL))
          if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL))
            continue;
            continue;
          if (no_print_builtins
          if (no_print_builtins
              && (TREE_CODE (t) == TYPE_DECL)
              && (TREE_CODE (t) == TYPE_DECL)
              && DECL_IS_BUILTIN (t))
              && DECL_IS_BUILTIN (t))
            continue;
            continue;
 
 
          /* Function decls tend to have longer names.  */
          /* Function decls tend to have longer names.  */
          if (TREE_CODE (t) == FUNCTION_DECL)
          if (TREE_CODE (t) == FUNCTION_DECL)
            len = 3;
            len = 3;
          else
          else
            len = 2;
            len = 2;
          i += len;
          i += len;
          if (i > 6)
          if (i > 6)
            {
            {
              fprintf (stderr, "\n\t");
              fprintf (stderr, "\n\t");
              i = len;
              i = len;
            }
            }
          print_node_brief (stderr, "", t, 0);
          print_node_brief (stderr, "", t, 0);
          if (t == error_mark_node)
          if (t == error_mark_node)
            break;
            break;
        }
        }
      if (i)
      if (i)
        fprintf (stderr, "\n");
        fprintf (stderr, "\n");
    }
    }
  if (VEC_length (cp_class_binding, lvl->class_shadowed))
  if (VEC_length (cp_class_binding, lvl->class_shadowed))
    {
    {
      size_t i;
      size_t i;
      cp_class_binding *b;
      cp_class_binding *b;
      fprintf (stderr, " class-shadowed:");
      fprintf (stderr, " class-shadowed:");
      for (i = 0;
      for (i = 0;
           VEC_iterate(cp_class_binding, lvl->class_shadowed, i, b);
           VEC_iterate(cp_class_binding, lvl->class_shadowed, i, b);
           ++i)
           ++i)
        fprintf (stderr, " %s ", IDENTIFIER_POINTER (b->identifier));
        fprintf (stderr, " %s ", IDENTIFIER_POINTER (b->identifier));
      fprintf (stderr, "\n");
      fprintf (stderr, "\n");
    }
    }
  if (lvl->type_shadowed)
  if (lvl->type_shadowed)
    {
    {
      fprintf (stderr, " type-shadowed:");
      fprintf (stderr, " type-shadowed:");
      for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t))
      for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t))
        {
        {
          fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
          fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
        }
        }
      fprintf (stderr, "\n");
      fprintf (stderr, "\n");
    }
    }
}
}
 
 
void
void
print_other_binding_stack (struct cp_binding_level *stack)
print_other_binding_stack (struct cp_binding_level *stack)
{
{
  struct cp_binding_level *level;
  struct cp_binding_level *level;
  for (level = stack; !global_scope_p (level); level = level->level_chain)
  for (level = stack; !global_scope_p (level); level = level->level_chain)
    {
    {
      fprintf (stderr, "binding level %p\n", (void *) level);
      fprintf (stderr, "binding level %p\n", (void *) level);
      print_binding_level (level);
      print_binding_level (level);
    }
    }
}
}
 
 
void
void
print_binding_stack (void)
print_binding_stack (void)
{
{
  struct cp_binding_level *b;
  struct cp_binding_level *b;
  fprintf (stderr, "current_binding_level=%p\n"
  fprintf (stderr, "current_binding_level=%p\n"
           "class_binding_level=%p\n"
           "class_binding_level=%p\n"
           "NAMESPACE_LEVEL (global_namespace)=%p\n",
           "NAMESPACE_LEVEL (global_namespace)=%p\n",
           (void *) current_binding_level, (void *) class_binding_level,
           (void *) current_binding_level, (void *) class_binding_level,
           (void *) NAMESPACE_LEVEL (global_namespace));
           (void *) NAMESPACE_LEVEL (global_namespace));
  if (class_binding_level)
  if (class_binding_level)
    {
    {
      for (b = class_binding_level; b; b = b->level_chain)
      for (b = class_binding_level; b; b = b->level_chain)
        if (b == current_binding_level)
        if (b == current_binding_level)
          break;
          break;
      if (b)
      if (b)
        b = class_binding_level;
        b = class_binding_level;
      else
      else
        b = current_binding_level;
        b = current_binding_level;
    }
    }
  else
  else
    b = current_binding_level;
    b = current_binding_level;
  print_other_binding_stack (b);
  print_other_binding_stack (b);
  fprintf (stderr, "global:\n");
  fprintf (stderr, "global:\n");
  print_binding_level (NAMESPACE_LEVEL (global_namespace));
  print_binding_level (NAMESPACE_LEVEL (global_namespace));
}
}


/* Return the type associated with id.  */
/* Return the type associated with id.  */
 
 
tree
tree
identifier_type_value (tree id)
identifier_type_value (tree id)
{
{
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  /* There is no type with that name, anywhere.  */
  /* There is no type with that name, anywhere.  */
  if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
  if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
  /* This is not the type marker, but the real thing.  */
  /* This is not the type marker, but the real thing.  */
  if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
  if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, REAL_IDENTIFIER_TYPE_VALUE (id));
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, REAL_IDENTIFIER_TYPE_VALUE (id));
  /* Have to search for it. It must be on the global level, now.
  /* Have to search for it. It must be on the global level, now.
     Ask lookup_name not to return non-types.  */
     Ask lookup_name not to return non-types.  */
  id = lookup_name_real (id, 2, 1, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
  id = lookup_name_real (id, 2, 1, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
  if (id)
  if (id)
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id));
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id));
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
}
 
 
/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
   the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
   the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
 
 
tree
tree
identifier_global_value (tree t)
identifier_global_value (tree t)
{
{
  return IDENTIFIER_GLOBAL_VALUE (t);
  return IDENTIFIER_GLOBAL_VALUE (t);
}
}
 
 
/* Push a definition of struct, union or enum tag named ID.  into
/* Push a definition of struct, union or enum tag named ID.  into
   binding_level B.  DECL is a TYPE_DECL for the type.  We assume that
   binding_level B.  DECL is a TYPE_DECL for the type.  We assume that
   the tag ID is not already defined.  */
   the tag ID is not already defined.  */
 
 
static void
static void
set_identifier_type_value_with_scope (tree id, tree decl, cxx_scope *b)
set_identifier_type_value_with_scope (tree id, tree decl, cxx_scope *b)
{
{
  tree type;
  tree type;
 
 
  if (b->kind != sk_namespace)
  if (b->kind != sk_namespace)
    {
    {
      /* Shadow the marker, not the real thing, so that the marker
      /* Shadow the marker, not the real thing, so that the marker
         gets restored later.  */
         gets restored later.  */
      tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
      tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
      b->type_shadowed
      b->type_shadowed
        = tree_cons (id, old_type_value, b->type_shadowed);
        = tree_cons (id, old_type_value, b->type_shadowed);
      type = decl ? TREE_TYPE (decl) : NULL_TREE;
      type = decl ? TREE_TYPE (decl) : NULL_TREE;
      TREE_TYPE (b->type_shadowed) = type;
      TREE_TYPE (b->type_shadowed) = type;
    }
    }
  else
  else
    {
    {
      cxx_binding *binding =
      cxx_binding *binding =
        binding_for_name (NAMESPACE_LEVEL (current_namespace), id);
        binding_for_name (NAMESPACE_LEVEL (current_namespace), id);
      gcc_assert (decl);
      gcc_assert (decl);
      if (binding->value)
      if (binding->value)
        supplement_binding (binding, decl);
        supplement_binding (binding, decl);
      else
      else
        binding->value = decl;
        binding->value = decl;
 
 
      /* Store marker instead of real type.  */
      /* Store marker instead of real type.  */
      type = global_type_node;
      type = global_type_node;
    }
    }
  SET_IDENTIFIER_TYPE_VALUE (id, type);
  SET_IDENTIFIER_TYPE_VALUE (id, type);
}
}
 
 
/* As set_identifier_type_value_with_scope, but using
/* As set_identifier_type_value_with_scope, but using
   current_binding_level.  */
   current_binding_level.  */
 
 
void
void
set_identifier_type_value (tree id, tree decl)
set_identifier_type_value (tree id, tree decl)
{
{
  set_identifier_type_value_with_scope (id, decl, current_binding_level);
  set_identifier_type_value_with_scope (id, decl, current_binding_level);
}
}
 
 
/* Return the name for the constructor (or destructor) for the
/* Return the name for the constructor (or destructor) for the
   specified class TYPE.  When given a template, this routine doesn't
   specified class TYPE.  When given a template, this routine doesn't
   lose the specialization.  */
   lose the specialization.  */
 
 
static inline tree
static inline tree
constructor_name_full (tree type)
constructor_name_full (tree type)
{
{
  return TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (type));
  return TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (type));
}
}
 
 
/* Return the name for the constructor (or destructor) for the
/* Return the name for the constructor (or destructor) for the
   specified class.  When given a template, return the plain
   specified class.  When given a template, return the plain
   unspecialized name.  */
   unspecialized name.  */
 
 
tree
tree
constructor_name (tree type)
constructor_name (tree type)
{
{
  tree name;
  tree name;
  name = constructor_name_full (type);
  name = constructor_name_full (type);
  if (IDENTIFIER_TEMPLATE (name))
  if (IDENTIFIER_TEMPLATE (name))
    name = IDENTIFIER_TEMPLATE (name);
    name = IDENTIFIER_TEMPLATE (name);
  return name;
  return name;
}
}
 
 
/* Returns TRUE if NAME is the name for the constructor for TYPE,
/* Returns TRUE if NAME is the name for the constructor for TYPE,
   which must be a class type.  */
   which must be a class type.  */
 
 
bool
bool
constructor_name_p (tree name, tree type)
constructor_name_p (tree name, tree type)
{
{
  tree ctor_name;
  tree ctor_name;
 
 
  gcc_assert (MAYBE_CLASS_TYPE_P (type));
  gcc_assert (MAYBE_CLASS_TYPE_P (type));
 
 
  if (!name)
  if (!name)
    return false;
    return false;
 
 
  if (TREE_CODE (name) != IDENTIFIER_NODE)
  if (TREE_CODE (name) != IDENTIFIER_NODE)
    return false;
    return false;
 
 
  ctor_name = constructor_name_full (type);
  ctor_name = constructor_name_full (type);
  if (name == ctor_name)
  if (name == ctor_name)
    return true;
    return true;
  if (IDENTIFIER_TEMPLATE (ctor_name)
  if (IDENTIFIER_TEMPLATE (ctor_name)
      && name == IDENTIFIER_TEMPLATE (ctor_name))
      && name == IDENTIFIER_TEMPLATE (ctor_name))
    return true;
    return true;
  return false;
  return false;
}
}
 
 
/* Counter used to create anonymous type names.  */
/* Counter used to create anonymous type names.  */
 
 
static GTY(()) int anon_cnt;
static GTY(()) int anon_cnt;
 
 
/* Return an IDENTIFIER which can be used as a name for
/* Return an IDENTIFIER which can be used as a name for
   anonymous structs and unions.  */
   anonymous structs and unions.  */
 
 
tree
tree
make_anon_name (void)
make_anon_name (void)
{
{
  char buf[32];
  char buf[32];
 
 
  sprintf (buf, ANON_AGGRNAME_FORMAT, anon_cnt++);
  sprintf (buf, ANON_AGGRNAME_FORMAT, anon_cnt++);
  return get_identifier (buf);
  return get_identifier (buf);
}
}
 
 
/* This code is practically identical to that for creating
/* This code is practically identical to that for creating
   anonymous names, but is just used for lambdas instead.  This is necessary
   anonymous names, but is just used for lambdas instead.  This is necessary
   because anonymous names are recognized and cannot be passed to template
   because anonymous names are recognized and cannot be passed to template
   functions.  */
   functions.  */
/* FIXME is this still necessary? */
/* FIXME is this still necessary? */
 
 
static GTY(()) int lambda_cnt = 0;
static GTY(()) int lambda_cnt = 0;
 
 
tree
tree
make_lambda_name (void)
make_lambda_name (void)
{
{
  char buf[32];
  char buf[32];
 
 
  sprintf (buf, LAMBDANAME_FORMAT, lambda_cnt++);
  sprintf (buf, LAMBDANAME_FORMAT, lambda_cnt++);
  return get_identifier (buf);
  return get_identifier (buf);
}
}
 
 
/* Return (from the stack of) the BINDING, if any, established at SCOPE.  */
/* Return (from the stack of) the BINDING, if any, established at SCOPE.  */
 
 
static inline cxx_binding *
static inline cxx_binding *
find_binding (cxx_scope *scope, cxx_binding *binding)
find_binding (cxx_scope *scope, cxx_binding *binding)
{
{
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
 
 
  for (; binding != NULL; binding = binding->previous)
  for (; binding != NULL; binding = binding->previous)
    if (binding->scope == scope)
    if (binding->scope == scope)
      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding);
      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding);
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (cxx_binding *)0);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (cxx_binding *)0);
}
}
 
 
/* Return the binding for NAME in SCOPE, if any.  Otherwise, return NULL.  */
/* Return the binding for NAME in SCOPE, if any.  Otherwise, return NULL.  */
 
 
static inline cxx_binding *
static inline cxx_binding *
cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)
cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)
{
{
  cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
  cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
  if (b)
  if (b)
    {
    {
      /* Fold-in case where NAME is used only once.  */
      /* Fold-in case where NAME is used only once.  */
      if (scope == b->scope && b->previous == NULL)
      if (scope == b->scope && b->previous == NULL)
        return b;
        return b;
      return find_binding (scope, b);
      return find_binding (scope, b);
    }
    }
  return NULL;
  return NULL;
}
}
 
 
/* Always returns a binding for name in scope.  If no binding is
/* Always returns a binding for name in scope.  If no binding is
   found, make a new one.  */
   found, make a new one.  */
 
 
static cxx_binding *
static cxx_binding *
binding_for_name (cxx_scope *scope, tree name)
binding_for_name (cxx_scope *scope, tree name)
{
{
  cxx_binding *result;
  cxx_binding *result;
 
 
  result = cxx_scope_find_binding_for_name (scope, name);
  result = cxx_scope_find_binding_for_name (scope, name);
  if (result)
  if (result)
    return result;
    return result;
  /* Not found, make a new one.  */
  /* Not found, make a new one.  */
  result = cxx_binding_make (NULL, NULL);
  result = cxx_binding_make (NULL, NULL);
  result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
  result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
  result->scope = scope;
  result->scope = scope;
  result->is_local = false;
  result->is_local = false;
  result->value_is_inherited = false;
  result->value_is_inherited = false;
  IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
  IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
  return result;
  return result;
}
}
 
 
/* Walk through the bindings associated to the name of FUNCTION,
/* Walk through the bindings associated to the name of FUNCTION,
   and return the first binding that declares a function with a
   and return the first binding that declares a function with a
   "C" linkage specification, a.k.a 'extern "C"'.
   "C" linkage specification, a.k.a 'extern "C"'.
   This function looks for the binding, regardless of which scope it
   This function looks for the binding, regardless of which scope it
   has been defined in. It basically looks in all the known scopes.
   has been defined in. It basically looks in all the known scopes.
   Note that this function does not lookup for bindings of builtin functions
   Note that this function does not lookup for bindings of builtin functions
   or for functions declared in system headers.  */
   or for functions declared in system headers.  */
static cxx_binding*
static cxx_binding*
lookup_extern_c_fun_binding_in_all_ns (tree function)
lookup_extern_c_fun_binding_in_all_ns (tree function)
{
{
  tree name;
  tree name;
  cxx_binding *iter;
  cxx_binding *iter;
 
 
  gcc_assert (function && TREE_CODE (function) == FUNCTION_DECL);
  gcc_assert (function && TREE_CODE (function) == FUNCTION_DECL);
 
 
  name = DECL_NAME (function);
  name = DECL_NAME (function);
  gcc_assert (name && TREE_CODE (name) == IDENTIFIER_NODE);
  gcc_assert (name && TREE_CODE (name) == IDENTIFIER_NODE);
 
 
  for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name);
  for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name);
       iter;
       iter;
       iter = iter->previous)
       iter = iter->previous)
    {
    {
      if (iter->value
      if (iter->value
          && TREE_CODE (iter->value) == FUNCTION_DECL
          && TREE_CODE (iter->value) == FUNCTION_DECL
          && DECL_EXTERN_C_P (iter->value)
          && DECL_EXTERN_C_P (iter->value)
          && !DECL_ARTIFICIAL (iter->value))
          && !DECL_ARTIFICIAL (iter->value))
        {
        {
          return iter;
          return iter;
        }
        }
    }
    }
  return NULL;
  return NULL;
}
}
 
 
/* Insert another USING_DECL into the current binding level, returning
/* Insert another USING_DECL into the current binding level, returning
   this declaration. If this is a redeclaration, do nothing, and
   this declaration. If this is a redeclaration, do nothing, and
   return NULL_TREE if this not in namespace scope (in namespace
   return NULL_TREE if this not in namespace scope (in namespace
   scope, a using decl might extend any previous bindings).  */
   scope, a using decl might extend any previous bindings).  */
 
 
static tree
static tree
push_using_decl (tree scope, tree name)
push_using_decl (tree scope, tree name)
{
{
  tree decl;
  tree decl;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL);
  gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL);
  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
  for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
  for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
    if (USING_DECL_SCOPE (decl) == scope && DECL_NAME (decl) == name)
    if (USING_DECL_SCOPE (decl) == scope && DECL_NAME (decl) == name)
      break;
      break;
  if (decl)
  if (decl)
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
                            namespace_bindings_p () ? decl : NULL_TREE);
                            namespace_bindings_p () ? decl : NULL_TREE);
  decl = build_lang_decl (USING_DECL, name, NULL_TREE);
  decl = build_lang_decl (USING_DECL, name, NULL_TREE);
  USING_DECL_SCOPE (decl) = scope;
  USING_DECL_SCOPE (decl) = scope;
  TREE_CHAIN (decl) = current_binding_level->usings;
  TREE_CHAIN (decl) = current_binding_level->usings;
  current_binding_level->usings = decl;
  current_binding_level->usings = decl;
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
}
 
 
/* Same as pushdecl, but define X in binding-level LEVEL.  We rely on the
/* Same as pushdecl, but define X in binding-level LEVEL.  We rely on the
   caller to set DECL_CONTEXT properly.  */
   caller to set DECL_CONTEXT properly.  */
 
 
tree
tree
pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend)
pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend)
{
{
  struct cp_binding_level *b;
  struct cp_binding_level *b;
  tree function_decl = current_function_decl;
  tree function_decl = current_function_decl;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  current_function_decl = NULL_TREE;
  current_function_decl = NULL_TREE;
  if (level->kind == sk_class)
  if (level->kind == sk_class)
    {
    {
      b = class_binding_level;
      b = class_binding_level;
      class_binding_level = level;
      class_binding_level = level;
      pushdecl_class_level (x);
      pushdecl_class_level (x);
      class_binding_level = b;
      class_binding_level = b;
    }
    }
  else
  else
    {
    {
      b = current_binding_level;
      b = current_binding_level;
      current_binding_level = level;
      current_binding_level = level;
      x = pushdecl_maybe_friend (x, is_friend);
      x = pushdecl_maybe_friend (x, is_friend);
      current_binding_level = b;
      current_binding_level = b;
    }
    }
  current_function_decl = function_decl;
  current_function_decl = function_decl;
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
}
}
 
 
/* DECL is a FUNCTION_DECL for a non-member function, which may have
/* DECL is a FUNCTION_DECL for a non-member function, which may have
   other definitions already in place.  We get around this by making
   other definitions already in place.  We get around this by making
   the value of the identifier point to a list of all the things that
   the value of the identifier point to a list of all the things that
   want to be referenced by that name.  It is then up to the users of
   want to be referenced by that name.  It is then up to the users of
   that name to decide what to do with that list.
   that name to decide what to do with that list.
 
 
   DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its
   DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its
   DECL_TEMPLATE_RESULT.  It is dealt with the same way.
   DECL_TEMPLATE_RESULT.  It is dealt with the same way.
 
 
   FLAGS is a bitwise-or of the following values:
   FLAGS is a bitwise-or of the following values:
     PUSH_LOCAL: Bind DECL in the current scope, rather than at
     PUSH_LOCAL: Bind DECL in the current scope, rather than at
                 namespace scope.
                 namespace scope.
     PUSH_USING: DECL is being pushed as the result of a using
     PUSH_USING: DECL is being pushed as the result of a using
                 declaration.
                 declaration.
 
 
   IS_FRIEND is true if this is a friend declaration.
   IS_FRIEND is true if this is a friend declaration.
 
 
   The value returned may be a previous declaration if we guessed wrong
   The value returned may be a previous declaration if we guessed wrong
   about what language DECL should belong to (C or C++).  Otherwise,
   about what language DECL should belong to (C or C++).  Otherwise,
   it's always DECL (and never something that's not a _DECL).  */
   it's always DECL (and never something that's not a _DECL).  */
 
 
static tree
static tree
push_overloaded_decl (tree decl, int flags, bool is_friend)
push_overloaded_decl (tree decl, int flags, bool is_friend)
{
{
  tree name = DECL_NAME (decl);
  tree name = DECL_NAME (decl);
  tree old;
  tree old;
  tree new_binding;
  tree new_binding;
  int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));
  int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  if (doing_global)
  if (doing_global)
    old = namespace_binding (name, DECL_CONTEXT (decl));
    old = namespace_binding (name, DECL_CONTEXT (decl));
  else
  else
    old = lookup_name_innermost_nonclass_level (name);
    old = lookup_name_innermost_nonclass_level (name);
 
 
  if (old)
  if (old)
    {
    {
      if (TREE_CODE (old) == TYPE_DECL && DECL_ARTIFICIAL (old))
      if (TREE_CODE (old) == TYPE_DECL && DECL_ARTIFICIAL (old))
        {
        {
          tree t = TREE_TYPE (old);
          tree t = TREE_TYPE (old);
          if (MAYBE_CLASS_TYPE_P (t) && warn_shadow
          if (MAYBE_CLASS_TYPE_P (t) && warn_shadow
              && (! DECL_IN_SYSTEM_HEADER (decl)
              && (! DECL_IN_SYSTEM_HEADER (decl)
                  || ! DECL_IN_SYSTEM_HEADER (old)))
                  || ! DECL_IN_SYSTEM_HEADER (old)))
            warning (OPT_Wshadow, "%q#D hides constructor for %q#T", decl, t);
            warning (OPT_Wshadow, "%q#D hides constructor for %q#T", decl, t);
          old = NULL_TREE;
          old = NULL_TREE;
        }
        }
      else if (is_overloaded_fn (old))
      else if (is_overloaded_fn (old))
        {
        {
          tree tmp;
          tree tmp;
 
 
          for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
          for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
            {
            {
              tree fn = OVL_CURRENT (tmp);
              tree fn = OVL_CURRENT (tmp);
              tree dup;
              tree dup;
 
 
              if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
              if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
                  && !(flags & PUSH_USING)
                  && !(flags & PUSH_USING)
                  && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
                  && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
                                TYPE_ARG_TYPES (TREE_TYPE (decl)))
                                TYPE_ARG_TYPES (TREE_TYPE (decl)))
                  && ! decls_match (fn, decl))
                  && ! decls_match (fn, decl))
                error ("%q#D conflicts with previous using declaration %q#D",
                error ("%q#D conflicts with previous using declaration %q#D",
                       decl, fn);
                       decl, fn);
 
 
              dup = duplicate_decls (decl, fn, is_friend);
              dup = duplicate_decls (decl, fn, is_friend);
              /* If DECL was a redeclaration of FN -- even an invalid
              /* If DECL was a redeclaration of FN -- even an invalid
                 one -- pass that information along to our caller.  */
                 one -- pass that information along to our caller.  */
              if (dup == fn || dup == error_mark_node)
              if (dup == fn || dup == error_mark_node)
                POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, dup);
                POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, dup);
            }
            }
 
 
          /* We don't overload implicit built-ins.  duplicate_decls()
          /* We don't overload implicit built-ins.  duplicate_decls()
             may fail to merge the decls if the new decl is e.g. a
             may fail to merge the decls if the new decl is e.g. a
             template function.  */
             template function.  */
          if (TREE_CODE (old) == FUNCTION_DECL
          if (TREE_CODE (old) == FUNCTION_DECL
              && DECL_ANTICIPATED (old)
              && DECL_ANTICIPATED (old)
              && !DECL_HIDDEN_FRIEND_P (old))
              && !DECL_HIDDEN_FRIEND_P (old))
            old = NULL;
            old = NULL;
        }
        }
      else if (old == error_mark_node)
      else if (old == error_mark_node)
        /* Ignore the undefined symbol marker.  */
        /* Ignore the undefined symbol marker.  */
        old = NULL_TREE;
        old = NULL_TREE;
      else
      else
        {
        {
          error ("previous non-function declaration %q+#D", old);
          error ("previous non-function declaration %q+#D", old);
          error ("conflicts with function declaration %q#D", decl);
          error ("conflicts with function declaration %q#D", decl);
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
        }
        }
    }
    }
 
 
  if (old || TREE_CODE (decl) == TEMPLATE_DECL
  if (old || TREE_CODE (decl) == TEMPLATE_DECL
      /* If it's a using declaration, we always need to build an OVERLOAD,
      /* If it's a using declaration, we always need to build an OVERLOAD,
         because it's the only way to remember that the declaration comes
         because it's the only way to remember that the declaration comes
         from 'using', and have the lookup behave correctly.  */
         from 'using', and have the lookup behave correctly.  */
      || (flags & PUSH_USING))
      || (flags & PUSH_USING))
    {
    {
      if (old && TREE_CODE (old) != OVERLOAD)
      if (old && TREE_CODE (old) != OVERLOAD)
        new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
        new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
      else
      else
        new_binding = ovl_cons (decl, old);
        new_binding = ovl_cons (decl, old);
      if (flags & PUSH_USING)
      if (flags & PUSH_USING)
        OVL_USED (new_binding) = 1;
        OVL_USED (new_binding) = 1;
    }
    }
  else
  else
    /* NAME is not ambiguous.  */
    /* NAME is not ambiguous.  */
    new_binding = decl;
    new_binding = decl;
 
 
  if (doing_global)
  if (doing_global)
    set_namespace_binding (name, current_namespace, new_binding);
    set_namespace_binding (name, current_namespace, new_binding);
  else
  else
    {
    {
      /* We only create an OVERLOAD if there was a previous binding at
      /* We only create an OVERLOAD if there was a previous binding at
         this level, or if decl is a template. In the former case, we
         this level, or if decl is a template. In the former case, we
         need to remove the old binding and replace it with the new
         need to remove the old binding and replace it with the new
         binding.  We must also run through the NAMES on the binding
         binding.  We must also run through the NAMES on the binding
         level where the name was bound to update the chain.  */
         level where the name was bound to update the chain.  */
 
 
      if (TREE_CODE (new_binding) == OVERLOAD && old)
      if (TREE_CODE (new_binding) == OVERLOAD && old)
        {
        {
          tree *d;
          tree *d;
 
 
          for (d = &IDENTIFIER_BINDING (name)->scope->names;
          for (d = &IDENTIFIER_BINDING (name)->scope->names;
               *d;
               *d;
               d = &TREE_CHAIN (*d))
               d = &TREE_CHAIN (*d))
            if (*d == old
            if (*d == old
                || (TREE_CODE (*d) == TREE_LIST
                || (TREE_CODE (*d) == TREE_LIST
                    && TREE_VALUE (*d) == old))
                    && TREE_VALUE (*d) == old))
              {
              {
                if (TREE_CODE (*d) == TREE_LIST)
                if (TREE_CODE (*d) == TREE_LIST)
                  /* Just replace the old binding with the new.  */
                  /* Just replace the old binding with the new.  */
                  TREE_VALUE (*d) = new_binding;
                  TREE_VALUE (*d) = new_binding;
                else
                else
                  /* Build a TREE_LIST to wrap the OVERLOAD.  */
                  /* Build a TREE_LIST to wrap the OVERLOAD.  */
                  *d = tree_cons (NULL_TREE, new_binding,
                  *d = tree_cons (NULL_TREE, new_binding,
                                  TREE_CHAIN (*d));
                                  TREE_CHAIN (*d));
 
 
                /* And update the cxx_binding node.  */
                /* And update the cxx_binding node.  */
                IDENTIFIER_BINDING (name)->value = new_binding;
                IDENTIFIER_BINDING (name)->value = new_binding;
                POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
                POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
              }
              }
 
 
          /* We should always find a previous binding in this case.  */
          /* We should always find a previous binding in this case.  */
          gcc_unreachable ();
          gcc_unreachable ();
        }
        }
 
 
      /* Install the new binding.  */
      /* Install the new binding.  */
      push_local_binding (name, new_binding, flags);
      push_local_binding (name, new_binding, flags);
    }
    }
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
}
 
 
/* Check a non-member using-declaration. Return the name and scope
/* Check a non-member using-declaration. Return the name and scope
   being used, and the USING_DECL, or NULL_TREE on failure.  */
   being used, and the USING_DECL, or NULL_TREE on failure.  */
 
 
static tree
static tree
validate_nonmember_using_decl (tree decl, tree scope, tree name)
validate_nonmember_using_decl (tree decl, tree scope, tree name)
{
{
  /* [namespace.udecl]
  /* [namespace.udecl]
       A using-declaration for a class member shall be a
       A using-declaration for a class member shall be a
       member-declaration.  */
       member-declaration.  */
  if (TYPE_P (scope))
  if (TYPE_P (scope))
    {
    {
      error ("%qT is not a namespace", scope);
      error ("%qT is not a namespace", scope);
      return NULL_TREE;
      return NULL_TREE;
    }
    }
  else if (scope == error_mark_node)
  else if (scope == error_mark_node)
    return NULL_TREE;
    return NULL_TREE;
 
 
  if (TREE_CODE (decl) == TEMPLATE_ID_EXPR)
  if (TREE_CODE (decl) == TEMPLATE_ID_EXPR)
    {
    {
      /* 7.3.3/5
      /* 7.3.3/5
           A using-declaration shall not name a template-id.  */
           A using-declaration shall not name a template-id.  */
      error ("a using-declaration cannot specify a template-id.  "
      error ("a using-declaration cannot specify a template-id.  "
             "Try %<using %D%>", name);
             "Try %<using %D%>", name);
      return NULL_TREE;
      return NULL_TREE;
    }
    }
 
 
  if (TREE_CODE (decl) == NAMESPACE_DECL)
  if (TREE_CODE (decl) == NAMESPACE_DECL)
    {
    {
      error ("namespace %qD not allowed in using-declaration", decl);
      error ("namespace %qD not allowed in using-declaration", decl);
      return NULL_TREE;
      return NULL_TREE;
    }
    }
 
 
  if (TREE_CODE (decl) == SCOPE_REF)
  if (TREE_CODE (decl) == SCOPE_REF)
    {
    {
      /* It's a nested name with template parameter dependent scope.
      /* It's a nested name with template parameter dependent scope.
         This can only be using-declaration for class member.  */
         This can only be using-declaration for class member.  */
      error ("%qT is not a namespace", TREE_OPERAND (decl, 0));
      error ("%qT is not a namespace", TREE_OPERAND (decl, 0));
      return NULL_TREE;
      return NULL_TREE;
    }
    }
 
 
  if (is_overloaded_fn (decl))
  if (is_overloaded_fn (decl))
    decl = get_first_fn (decl);
    decl = get_first_fn (decl);
 
 
  gcc_assert (DECL_P (decl));
  gcc_assert (DECL_P (decl));
 
 
  /* Make a USING_DECL.  */
  /* Make a USING_DECL.  */
  return push_using_decl (scope, name);
  return push_using_decl (scope, name);
}
}
 
 
/* Process local and global using-declarations.  */
/* Process local and global using-declarations.  */
 
 
static void
static void
do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
                         tree *newval, tree *newtype)
                         tree *newval, tree *newtype)
{
{
  struct scope_binding decls = EMPTY_SCOPE_BINDING;
  struct scope_binding decls = EMPTY_SCOPE_BINDING;
 
 
  *newval = *newtype = NULL_TREE;
  *newval = *newtype = NULL_TREE;
  if (!qualified_lookup_using_namespace (name, scope, &decls, 0))
  if (!qualified_lookup_using_namespace (name, scope, &decls, 0))
    /* Lookup error */
    /* Lookup error */
    return;
    return;
 
 
  if (!decls.value && !decls.type)
  if (!decls.value && !decls.type)
    {
    {
      error ("%qD not declared", name);
      error ("%qD not declared", name);
      return;
      return;
    }
    }
 
 
  /* Shift the old and new bindings around so we're comparing class and
  /* Shift the old and new bindings around so we're comparing class and
     enumeration names to each other.  */
     enumeration names to each other.  */
  if (oldval && DECL_IMPLICIT_TYPEDEF_P (oldval))
  if (oldval && DECL_IMPLICIT_TYPEDEF_P (oldval))
    {
    {
      oldtype = oldval;
      oldtype = oldval;
      oldval = NULL_TREE;
      oldval = NULL_TREE;
    }
    }
 
 
  if (decls.value && DECL_IMPLICIT_TYPEDEF_P (decls.value))
  if (decls.value && DECL_IMPLICIT_TYPEDEF_P (decls.value))
    {
    {
      decls.type = decls.value;
      decls.type = decls.value;
      decls.value = NULL_TREE;
      decls.value = NULL_TREE;
    }
    }
 
 
  /* It is impossible to overload a built-in function; any explicit
  /* It is impossible to overload a built-in function; any explicit
     declaration eliminates the built-in declaration.  So, if OLDVAL
     declaration eliminates the built-in declaration.  So, if OLDVAL
     is a built-in, then we can just pretend it isn't there.  */
     is a built-in, then we can just pretend it isn't there.  */
  if (oldval
  if (oldval
      && TREE_CODE (oldval) == FUNCTION_DECL
      && TREE_CODE (oldval) == FUNCTION_DECL
      && DECL_ANTICIPATED (oldval)
      && DECL_ANTICIPATED (oldval)
      && !DECL_HIDDEN_FRIEND_P (oldval))
      && !DECL_HIDDEN_FRIEND_P (oldval))
    oldval = NULL_TREE;
    oldval = NULL_TREE;
 
 
  if (decls.value)
  if (decls.value)
    {
    {
      /* Check for using functions.  */
      /* Check for using functions.  */
      if (is_overloaded_fn (decls.value))
      if (is_overloaded_fn (decls.value))
        {
        {
          tree tmp, tmp1;
          tree tmp, tmp1;
 
 
          if (oldval && !is_overloaded_fn (oldval))
          if (oldval && !is_overloaded_fn (oldval))
            {
            {
              error ("%qD is already declared in this scope", name);
              error ("%qD is already declared in this scope", name);
              oldval = NULL_TREE;
              oldval = NULL_TREE;
            }
            }
 
 
          *newval = oldval;
          *newval = oldval;
          for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
          for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
            {
            {
              tree new_fn = OVL_CURRENT (tmp);
              tree new_fn = OVL_CURRENT (tmp);
 
 
              /* [namespace.udecl]
              /* [namespace.udecl]
 
 
                 If a function declaration in namespace scope or block
                 If a function declaration in namespace scope or block
                 scope has the same name and the same parameter types as a
                 scope has the same name and the same parameter types as a
                 function introduced by a using declaration the program is
                 function introduced by a using declaration the program is
                 ill-formed.  */
                 ill-formed.  */
              for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
              for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
                {
                {
                  tree old_fn = OVL_CURRENT (tmp1);
                  tree old_fn = OVL_CURRENT (tmp1);
 
 
                  if (new_fn == old_fn)
                  if (new_fn == old_fn)
                    /* The function already exists in the current namespace.  */
                    /* The function already exists in the current namespace.  */
                    break;
                    break;
                  else if (OVL_USED (tmp1))
                  else if (OVL_USED (tmp1))
                    continue; /* this is a using decl */
                    continue; /* this is a using decl */
                  else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
                  else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
                                      TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
                                      TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
                    {
                    {
                      gcc_assert (!DECL_ANTICIPATED (old_fn)
                      gcc_assert (!DECL_ANTICIPATED (old_fn)
                                  || DECL_HIDDEN_FRIEND_P (old_fn));
                                  || DECL_HIDDEN_FRIEND_P (old_fn));
 
 
                      /* There was already a non-using declaration in
                      /* There was already a non-using declaration in
                         this scope with the same parameter types. If both
                         this scope with the same parameter types. If both
                         are the same extern "C" functions, that's ok.  */
                         are the same extern "C" functions, that's ok.  */
                      if (decls_match (new_fn, old_fn))
                      if (decls_match (new_fn, old_fn))
                        break;
                        break;
                      else
                      else
                        {
                        {
                          error ("%qD is already declared in this scope", name);
                          error ("%qD is already declared in this scope", name);
                          break;
                          break;
                        }
                        }
                    }
                    }
                }
                }
 
 
              /* If we broke out of the loop, there's no reason to add
              /* If we broke out of the loop, there's no reason to add
                 this function to the using declarations for this
                 this function to the using declarations for this
                 scope.  */
                 scope.  */
              if (tmp1)
              if (tmp1)
                continue;
                continue;
 
 
              /* If we are adding to an existing OVERLOAD, then we no
              /* If we are adding to an existing OVERLOAD, then we no
                 longer know the type of the set of functions.  */
                 longer know the type of the set of functions.  */
              if (*newval && TREE_CODE (*newval) == OVERLOAD)
              if (*newval && TREE_CODE (*newval) == OVERLOAD)
                TREE_TYPE (*newval) = unknown_type_node;
                TREE_TYPE (*newval) = unknown_type_node;
              /* Add this new function to the set.  */
              /* Add this new function to the set.  */
              *newval = build_overload (OVL_CURRENT (tmp), *newval);
              *newval = build_overload (OVL_CURRENT (tmp), *newval);
              /* If there is only one function, then we use its type.  (A
              /* If there is only one function, then we use its type.  (A
                 using-declaration naming a single function can be used in
                 using-declaration naming a single function can be used in
                 contexts where overload resolution cannot be
                 contexts where overload resolution cannot be
                 performed.)  */
                 performed.)  */
              if (TREE_CODE (*newval) != OVERLOAD)
              if (TREE_CODE (*newval) != OVERLOAD)
                {
                {
                  *newval = ovl_cons (*newval, NULL_TREE);
                  *newval = ovl_cons (*newval, NULL_TREE);
                  TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
                  TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
                }
                }
              OVL_USED (*newval) = 1;
              OVL_USED (*newval) = 1;
            }
            }
        }
        }
      else
      else
        {
        {
          *newval = decls.value;
          *newval = decls.value;
          if (oldval && !decls_match (*newval, oldval))
          if (oldval && !decls_match (*newval, oldval))
            error ("%qD is already declared in this scope", name);
            error ("%qD is already declared in this scope", name);
        }
        }
    }
    }
  else
  else
    *newval = oldval;
    *newval = oldval;
 
 
  if (decls.type && TREE_CODE (decls.type) == TREE_LIST)
  if (decls.type && TREE_CODE (decls.type) == TREE_LIST)
    {
    {
      error ("reference to %qD is ambiguous", name);
      error ("reference to %qD is ambiguous", name);
      print_candidates (decls.type);
      print_candidates (decls.type);
    }
    }
  else
  else
    {
    {
      *newtype = decls.type;
      *newtype = decls.type;
      if (oldtype && *newtype && !decls_match (oldtype, *newtype))
      if (oldtype && *newtype && !decls_match (oldtype, *newtype))
        error ("%qD is already declared in this scope", name);
        error ("%qD is already declared in this scope", name);
    }
    }
 
 
    /* If *newval is empty, shift any class or enumeration name down.  */
    /* If *newval is empty, shift any class or enumeration name down.  */
    if (!*newval)
    if (!*newval)
      {
      {
        *newval = *newtype;
        *newval = *newtype;
        *newtype = NULL_TREE;
        *newtype = NULL_TREE;
      }
      }
}
}
 
 
/* Process a using-declaration at function scope.  */
/* Process a using-declaration at function scope.  */
 
 
void
void
do_local_using_decl (tree decl, tree scope, tree name)
do_local_using_decl (tree decl, tree scope, tree name)
{
{
  tree oldval, oldtype, newval, newtype;
  tree oldval, oldtype, newval, newtype;
  tree orig_decl = decl;
  tree orig_decl = decl;
 
 
  decl = validate_nonmember_using_decl (decl, scope, name);
  decl = validate_nonmember_using_decl (decl, scope, name);
  if (decl == NULL_TREE)
  if (decl == NULL_TREE)
    return;
    return;
 
 
  if (building_stmt_tree ()
  if (building_stmt_tree ()
      && at_function_scope_p ())
      && at_function_scope_p ())
    add_decl_expr (decl);
    add_decl_expr (decl);
 
 
  oldval = lookup_name_innermost_nonclass_level (name);
  oldval = lookup_name_innermost_nonclass_level (name);
  oldtype = lookup_type_current_level (name);
  oldtype = lookup_type_current_level (name);
 
 
  do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
  do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
 
 
  if (newval)
  if (newval)
    {
    {
      if (is_overloaded_fn (newval))
      if (is_overloaded_fn (newval))
        {
        {
          tree fn, term;
          tree fn, term;
 
 
          /* We only need to push declarations for those functions
          /* We only need to push declarations for those functions
             that were not already bound in the current level.
             that were not already bound in the current level.
             The old value might be NULL_TREE, it might be a single
             The old value might be NULL_TREE, it might be a single
             function, or an OVERLOAD.  */
             function, or an OVERLOAD.  */
          if (oldval && TREE_CODE (oldval) == OVERLOAD)
          if (oldval && TREE_CODE (oldval) == OVERLOAD)
            term = OVL_FUNCTION (oldval);
            term = OVL_FUNCTION (oldval);
          else
          else
            term = oldval;
            term = oldval;
          for (fn = newval; fn && OVL_CURRENT (fn) != term;
          for (fn = newval; fn && OVL_CURRENT (fn) != term;
               fn = OVL_NEXT (fn))
               fn = OVL_NEXT (fn))
            push_overloaded_decl (OVL_CURRENT (fn),
            push_overloaded_decl (OVL_CURRENT (fn),
                                  PUSH_LOCAL | PUSH_USING,
                                  PUSH_LOCAL | PUSH_USING,
                                  false);
                                  false);
        }
        }
      else
      else
        push_local_binding (name, newval, PUSH_USING);
        push_local_binding (name, newval, PUSH_USING);
    }
    }
  if (newtype)
  if (newtype)
    {
    {
      push_local_binding (name, newtype, PUSH_USING);
      push_local_binding (name, newtype, PUSH_USING);
      set_identifier_type_value (name, newtype);
      set_identifier_type_value (name, newtype);
    }
    }
 
 
  /* Emit debug info.  */
  /* Emit debug info.  */
  if (!processing_template_decl)
  if (!processing_template_decl)
    cp_emit_debug_info_for_using (orig_decl, current_scope());
    cp_emit_debug_info_for_using (orig_decl, current_scope());
}
}
 
 
/* Returns true if ROOT (a namespace, class, or function) encloses
/* Returns true if ROOT (a namespace, class, or function) encloses
   CHILD.  CHILD may be either a class type or a namespace.  */
   CHILD.  CHILD may be either a class type or a namespace.  */
 
 
bool
bool
is_ancestor (tree root, tree child)
is_ancestor (tree root, tree child)
{
{
  gcc_assert ((TREE_CODE (root) == NAMESPACE_DECL
  gcc_assert ((TREE_CODE (root) == NAMESPACE_DECL
               || TREE_CODE (root) == FUNCTION_DECL
               || TREE_CODE (root) == FUNCTION_DECL
               || CLASS_TYPE_P (root)));
               || CLASS_TYPE_P (root)));
  gcc_assert ((TREE_CODE (child) == NAMESPACE_DECL
  gcc_assert ((TREE_CODE (child) == NAMESPACE_DECL
               || CLASS_TYPE_P (child)));
               || CLASS_TYPE_P (child)));
 
 
  /* The global namespace encloses everything.  */
  /* The global namespace encloses everything.  */
  if (root == global_namespace)
  if (root == global_namespace)
    return true;
    return true;
 
 
  while (true)
  while (true)
    {
    {
      /* If we've run out of scopes, stop.  */
      /* If we've run out of scopes, stop.  */
      if (!child)
      if (!child)
        return false;
        return false;
      /* If we've reached the ROOT, it encloses CHILD.  */
      /* If we've reached the ROOT, it encloses CHILD.  */
      if (root == child)
      if (root == child)
        return true;
        return true;
      /* Go out one level.  */
      /* Go out one level.  */
      if (TYPE_P (child))
      if (TYPE_P (child))
        child = TYPE_NAME (child);
        child = TYPE_NAME (child);
      child = DECL_CONTEXT (child);
      child = DECL_CONTEXT (child);
    }
    }
}
}
 
 
/* Enter the class or namespace scope indicated by T suitable for name
/* Enter the class or namespace scope indicated by T suitable for name
   lookup.  T can be arbitrary scope, not necessary nested inside the
   lookup.  T can be arbitrary scope, not necessary nested inside the
   current scope.  Returns a non-null scope to pop iff pop_scope
   current scope.  Returns a non-null scope to pop iff pop_scope
   should be called later to exit this scope.  */
   should be called later to exit this scope.  */
 
 
tree
tree
push_scope (tree t)
push_scope (tree t)
{
{
  if (TREE_CODE (t) == NAMESPACE_DECL)
  if (TREE_CODE (t) == NAMESPACE_DECL)
    push_decl_namespace (t);
    push_decl_namespace (t);
  else if (CLASS_TYPE_P (t))
  else if (CLASS_TYPE_P (t))
    {
    {
      if (!at_class_scope_p ()
      if (!at_class_scope_p ()
          || !same_type_p (current_class_type, t))
          || !same_type_p (current_class_type, t))
        push_nested_class (t);
        push_nested_class (t);
      else
      else
        /* T is the same as the current scope.  There is therefore no
        /* T is the same as the current scope.  There is therefore no
           need to re-enter the scope.  Since we are not actually
           need to re-enter the scope.  Since we are not actually
           pushing a new scope, our caller should not call
           pushing a new scope, our caller should not call
           pop_scope.  */
           pop_scope.  */
        t = NULL_TREE;
        t = NULL_TREE;
    }
    }
 
 
  return t;
  return t;
}
}
 
 
/* Leave scope pushed by push_scope.  */
/* Leave scope pushed by push_scope.  */
 
 
void
void
pop_scope (tree t)
pop_scope (tree t)
{
{
  if (TREE_CODE (t) == NAMESPACE_DECL)
  if (TREE_CODE (t) == NAMESPACE_DECL)
    pop_decl_namespace ();
    pop_decl_namespace ();
  else if CLASS_TYPE_P (t)
  else if CLASS_TYPE_P (t)
    pop_nested_class ();
    pop_nested_class ();
}
}
 
 
/* Subroutine of push_inner_scope.  */
/* Subroutine of push_inner_scope.  */
 
 
static void
static void
push_inner_scope_r (tree outer, tree inner)
push_inner_scope_r (tree outer, tree inner)
{
{
  tree prev;
  tree prev;
 
 
  if (outer == inner
  if (outer == inner
      || (TREE_CODE (inner) != NAMESPACE_DECL && !CLASS_TYPE_P (inner)))
      || (TREE_CODE (inner) != NAMESPACE_DECL && !CLASS_TYPE_P (inner)))
    return;
    return;
 
 
  prev = CP_DECL_CONTEXT (TREE_CODE (inner) == NAMESPACE_DECL ? inner : TYPE_NAME (inner));
  prev = CP_DECL_CONTEXT (TREE_CODE (inner) == NAMESPACE_DECL ? inner : TYPE_NAME (inner));
  if (outer != prev)
  if (outer != prev)
    push_inner_scope_r (outer, prev);
    push_inner_scope_r (outer, prev);
  if (TREE_CODE (inner) == NAMESPACE_DECL)
  if (TREE_CODE (inner) == NAMESPACE_DECL)
    {
    {
      struct cp_binding_level *save_template_parm = 0;
      struct cp_binding_level *save_template_parm = 0;
      /* Temporary take out template parameter scopes.  They are saved
      /* Temporary take out template parameter scopes.  They are saved
         in reversed order in save_template_parm.  */
         in reversed order in save_template_parm.  */
      while (current_binding_level->kind == sk_template_parms)
      while (current_binding_level->kind == sk_template_parms)
        {
        {
          struct cp_binding_level *b = current_binding_level;
          struct cp_binding_level *b = current_binding_level;
          current_binding_level = b->level_chain;
          current_binding_level = b->level_chain;
          b->level_chain = save_template_parm;
          b->level_chain = save_template_parm;
          save_template_parm = b;
          save_template_parm = b;
        }
        }
 
 
      resume_scope (NAMESPACE_LEVEL (inner));
      resume_scope (NAMESPACE_LEVEL (inner));
      current_namespace = inner;
      current_namespace = inner;
 
 
      /* Restore template parameter scopes.  */
      /* Restore template parameter scopes.  */
      while (save_template_parm)
      while (save_template_parm)
        {
        {
          struct cp_binding_level *b = save_template_parm;
          struct cp_binding_level *b = save_template_parm;
          save_template_parm = b->level_chain;
          save_template_parm = b->level_chain;
          b->level_chain = current_binding_level;
          b->level_chain = current_binding_level;
          current_binding_level = b;
          current_binding_level = b;
        }
        }
    }
    }
  else
  else
    pushclass (inner);
    pushclass (inner);
}
}
 
 
/* Enter the scope INNER from current scope.  INNER must be a scope
/* Enter the scope INNER from current scope.  INNER must be a scope
   nested inside current scope.  This works with both name lookup and
   nested inside current scope.  This works with both name lookup and
   pushing name into scope.  In case a template parameter scope is present,
   pushing name into scope.  In case a template parameter scope is present,
   namespace is pushed under the template parameter scope according to
   namespace is pushed under the template parameter scope according to
   name lookup rule in 14.6.1/6.
   name lookup rule in 14.6.1/6.
 
 
   Return the former current scope suitable for pop_inner_scope.  */
   Return the former current scope suitable for pop_inner_scope.  */
 
 
tree
tree
push_inner_scope (tree inner)
push_inner_scope (tree inner)
{
{
  tree outer = current_scope ();
  tree outer = current_scope ();
  if (!outer)
  if (!outer)
    outer = current_namespace;
    outer = current_namespace;
 
 
  push_inner_scope_r (outer, inner);
  push_inner_scope_r (outer, inner);
  return outer;
  return outer;
}
}
 
 
/* Exit the current scope INNER back to scope OUTER.  */
/* Exit the current scope INNER back to scope OUTER.  */
 
 
void
void
pop_inner_scope (tree outer, tree inner)
pop_inner_scope (tree outer, tree inner)
{
{
  if (outer == inner
  if (outer == inner
      || (TREE_CODE (inner) != NAMESPACE_DECL && !CLASS_TYPE_P (inner)))
      || (TREE_CODE (inner) != NAMESPACE_DECL && !CLASS_TYPE_P (inner)))
    return;
    return;
 
 
  while (outer != inner)
  while (outer != inner)
    {
    {
      if (TREE_CODE (inner) == NAMESPACE_DECL)
      if (TREE_CODE (inner) == NAMESPACE_DECL)
        {
        {
          struct cp_binding_level *save_template_parm = 0;
          struct cp_binding_level *save_template_parm = 0;
          /* Temporary take out template parameter scopes.  They are saved
          /* Temporary take out template parameter scopes.  They are saved
             in reversed order in save_template_parm.  */
             in reversed order in save_template_parm.  */
          while (current_binding_level->kind == sk_template_parms)
          while (current_binding_level->kind == sk_template_parms)
            {
            {
              struct cp_binding_level *b = current_binding_level;
              struct cp_binding_level *b = current_binding_level;
              current_binding_level = b->level_chain;
              current_binding_level = b->level_chain;
              b->level_chain = save_template_parm;
              b->level_chain = save_template_parm;
              save_template_parm = b;
              save_template_parm = b;
            }
            }
 
 
          pop_namespace ();
          pop_namespace ();
 
 
          /* Restore template parameter scopes.  */
          /* Restore template parameter scopes.  */
          while (save_template_parm)
          while (save_template_parm)
            {
            {
              struct cp_binding_level *b = save_template_parm;
              struct cp_binding_level *b = save_template_parm;
              save_template_parm = b->level_chain;
              save_template_parm = b->level_chain;
              b->level_chain = current_binding_level;
              b->level_chain = current_binding_level;
              current_binding_level = b;
              current_binding_level = b;
            }
            }
        }
        }
      else
      else
        popclass ();
        popclass ();
 
 
      inner = CP_DECL_CONTEXT (TREE_CODE (inner) == NAMESPACE_DECL ? inner : TYPE_NAME (inner));
      inner = CP_DECL_CONTEXT (TREE_CODE (inner) == NAMESPACE_DECL ? inner : TYPE_NAME (inner));
    }
    }
}
}


/* Do a pushlevel for class declarations.  */
/* Do a pushlevel for class declarations.  */
 
 
void
void
pushlevel_class (void)
pushlevel_class (void)
{
{
  class_binding_level = begin_scope (sk_class, current_class_type);
  class_binding_level = begin_scope (sk_class, current_class_type);
}
}
 
 
/* ...and a poplevel for class declarations.  */
/* ...and a poplevel for class declarations.  */
 
 
void
void
poplevel_class (void)
poplevel_class (void)
{
{
  struct cp_binding_level *level = class_binding_level;
  struct cp_binding_level *level = class_binding_level;
  cp_class_binding *cb;
  cp_class_binding *cb;
  size_t i;
  size_t i;
  tree shadowed;
  tree shadowed;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  gcc_assert (level != 0);
  gcc_assert (level != 0);
 
 
  /* If we're leaving a toplevel class, cache its binding level.  */
  /* If we're leaving a toplevel class, cache its binding level.  */
  if (current_class_depth == 1)
  if (current_class_depth == 1)
    previous_class_level = level;
    previous_class_level = level;
  for (shadowed = level->type_shadowed;
  for (shadowed = level->type_shadowed;
       shadowed;
       shadowed;
       shadowed = TREE_CHAIN (shadowed))
       shadowed = TREE_CHAIN (shadowed))
    SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
    SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
 
 
  /* Remove the bindings for all of the class-level declarations.  */
  /* Remove the bindings for all of the class-level declarations.  */
  if (level->class_shadowed)
  if (level->class_shadowed)
    {
    {
      for (i = 0;
      for (i = 0;
           VEC_iterate (cp_class_binding, level->class_shadowed, i, cb);
           VEC_iterate (cp_class_binding, level->class_shadowed, i, cb);
           ++i)
           ++i)
        IDENTIFIER_BINDING (cb->identifier) = cb->base.previous;
        IDENTIFIER_BINDING (cb->identifier) = cb->base.previous;
      ggc_free (level->class_shadowed);
      ggc_free (level->class_shadowed);
      level->class_shadowed = NULL;
      level->class_shadowed = NULL;
    }
    }
 
 
  /* Now, pop out of the binding level which we created up in the
  /* Now, pop out of the binding level which we created up in the
     `pushlevel_class' routine.  */
     `pushlevel_class' routine.  */
  gcc_assert (current_binding_level == level);
  gcc_assert (current_binding_level == level);
  leave_scope ();
  leave_scope ();
  timevar_pop (TV_NAME_LOOKUP);
  timevar_pop (TV_NAME_LOOKUP);
}
}
 
 
/* Set INHERITED_VALUE_BINDING_P on BINDING to true or false, as
/* Set INHERITED_VALUE_BINDING_P on BINDING to true or false, as
   appropriate.  DECL is the value to which a name has just been
   appropriate.  DECL is the value to which a name has just been
   bound.  CLASS_TYPE is the class in which the lookup occurred.  */
   bound.  CLASS_TYPE is the class in which the lookup occurred.  */
 
 
static void
static void
set_inherited_value_binding_p (cxx_binding *binding, tree decl,
set_inherited_value_binding_p (cxx_binding *binding, tree decl,
                               tree class_type)
                               tree class_type)
{
{
  if (binding->value == decl && TREE_CODE (decl) != TREE_LIST)
  if (binding->value == decl && TREE_CODE (decl) != TREE_LIST)
    {
    {
      tree context;
      tree context;
 
 
      if (TREE_CODE (decl) == OVERLOAD)
      if (TREE_CODE (decl) == OVERLOAD)
        context = CP_DECL_CONTEXT (OVL_CURRENT (decl));
        context = CP_DECL_CONTEXT (OVL_CURRENT (decl));
      else
      else
        {
        {
          gcc_assert (DECL_P (decl));
          gcc_assert (DECL_P (decl));
          context = context_for_name_lookup (decl);
          context = context_for_name_lookup (decl);
        }
        }
 
 
      if (is_properly_derived_from (class_type, context))
      if (is_properly_derived_from (class_type, context))
        INHERITED_VALUE_BINDING_P (binding) = 1;
        INHERITED_VALUE_BINDING_P (binding) = 1;
      else
      else
        INHERITED_VALUE_BINDING_P (binding) = 0;
        INHERITED_VALUE_BINDING_P (binding) = 0;
    }
    }
  else if (binding->value == decl)
  else if (binding->value == decl)
    /* We only encounter a TREE_LIST when there is an ambiguity in the
    /* We only encounter a TREE_LIST when there is an ambiguity in the
       base classes.  Such an ambiguity can be overridden by a
       base classes.  Such an ambiguity can be overridden by a
       definition in this class.  */
       definition in this class.  */
    INHERITED_VALUE_BINDING_P (binding) = 1;
    INHERITED_VALUE_BINDING_P (binding) = 1;
  else
  else
    INHERITED_VALUE_BINDING_P (binding) = 0;
    INHERITED_VALUE_BINDING_P (binding) = 0;
}
}
 
 
/* Make the declaration of X appear in CLASS scope.  */
/* Make the declaration of X appear in CLASS scope.  */
 
 
bool
bool
pushdecl_class_level (tree x)
pushdecl_class_level (tree x)
{
{
  tree name;
  tree name;
  bool is_valid = true;
  bool is_valid = true;
 
 
  /* Do nothing if we're adding to an outer lambda closure type,
  /* Do nothing if we're adding to an outer lambda closure type,
     outer_binding will add it later if it's needed.  */
     outer_binding will add it later if it's needed.  */
  if (current_class_type != class_binding_level->this_entity)
  if (current_class_type != class_binding_level->this_entity)
    return true;
    return true;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  /* Get the name of X.  */
  /* Get the name of X.  */
  if (TREE_CODE (x) == OVERLOAD)
  if (TREE_CODE (x) == OVERLOAD)
    name = DECL_NAME (get_first_fn (x));
    name = DECL_NAME (get_first_fn (x));
  else
  else
    name = DECL_NAME (x);
    name = DECL_NAME (x);
 
 
  if (name)
  if (name)
    {
    {
      is_valid = push_class_level_binding (name, x);
      is_valid = push_class_level_binding (name, x);
      if (TREE_CODE (x) == TYPE_DECL)
      if (TREE_CODE (x) == TYPE_DECL)
        set_identifier_type_value (name, x);
        set_identifier_type_value (name, x);
    }
    }
  else if (ANON_AGGR_TYPE_P (TREE_TYPE (x)))
  else if (ANON_AGGR_TYPE_P (TREE_TYPE (x)))
    {
    {
      /* If X is an anonymous aggregate, all of its members are
      /* If X is an anonymous aggregate, all of its members are
         treated as if they were members of the class containing the
         treated as if they were members of the class containing the
         aggregate, for naming purposes.  */
         aggregate, for naming purposes.  */
      tree f;
      tree f;
 
 
      for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f))
      for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f))
        {
        {
          location_t save_location = input_location;
          location_t save_location = input_location;
          input_location = DECL_SOURCE_LOCATION (f);
          input_location = DECL_SOURCE_LOCATION (f);
          if (!pushdecl_class_level (f))
          if (!pushdecl_class_level (f))
            is_valid = false;
            is_valid = false;
          input_location = save_location;
          input_location = save_location;
        }
        }
    }
    }
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, is_valid);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, is_valid);
}
}
 
 
/* Return the BINDING (if any) for NAME in SCOPE, which is a class
/* Return the BINDING (if any) for NAME in SCOPE, which is a class
   scope.  If the value returned is non-NULL, and the PREVIOUS field
   scope.  If the value returned is non-NULL, and the PREVIOUS field
   is not set, callers must set the PREVIOUS field explicitly.  */
   is not set, callers must set the PREVIOUS field explicitly.  */
 
 
static cxx_binding *
static cxx_binding *
get_class_binding (tree name, cxx_scope *scope)
get_class_binding (tree name, cxx_scope *scope)
{
{
  tree class_type;
  tree class_type;
  tree type_binding;
  tree type_binding;
  tree value_binding;
  tree value_binding;
  cxx_binding *binding;
  cxx_binding *binding;
 
 
  class_type = scope->this_entity;
  class_type = scope->this_entity;
 
 
  /* Get the type binding.  */
  /* Get the type binding.  */
  type_binding = lookup_member (class_type, name,
  type_binding = lookup_member (class_type, name,
                                /*protect=*/2, /*want_type=*/true);
                                /*protect=*/2, /*want_type=*/true);
  /* Get the value binding.  */
  /* Get the value binding.  */
  value_binding = lookup_member (class_type, name,
  value_binding = lookup_member (class_type, name,
                                 /*protect=*/2, /*want_type=*/false);
                                 /*protect=*/2, /*want_type=*/false);
 
 
  if (value_binding
  if (value_binding
      && (TREE_CODE (value_binding) == TYPE_DECL
      && (TREE_CODE (value_binding) == TYPE_DECL
          || DECL_CLASS_TEMPLATE_P (value_binding)
          || DECL_CLASS_TEMPLATE_P (value_binding)
          || (TREE_CODE (value_binding) == TREE_LIST
          || (TREE_CODE (value_binding) == TREE_LIST
              && TREE_TYPE (value_binding) == error_mark_node
              && TREE_TYPE (value_binding) == error_mark_node
              && (TREE_CODE (TREE_VALUE (value_binding))
              && (TREE_CODE (TREE_VALUE (value_binding))
                  == TYPE_DECL))))
                  == TYPE_DECL))))
    /* We found a type binding, even when looking for a non-type
    /* We found a type binding, even when looking for a non-type
       binding.  This means that we already processed this binding
       binding.  This means that we already processed this binding
       above.  */
       above.  */
    ;
    ;
  else if (value_binding)
  else if (value_binding)
    {
    {
      if (TREE_CODE (value_binding) == TREE_LIST
      if (TREE_CODE (value_binding) == TREE_LIST
          && TREE_TYPE (value_binding) == error_mark_node)
          && TREE_TYPE (value_binding) == error_mark_node)
        /* NAME is ambiguous.  */
        /* NAME is ambiguous.  */
        ;
        ;
      else if (BASELINK_P (value_binding))
      else if (BASELINK_P (value_binding))
        /* NAME is some overloaded functions.  */
        /* NAME is some overloaded functions.  */
        value_binding = BASELINK_FUNCTIONS (value_binding);
        value_binding = BASELINK_FUNCTIONS (value_binding);
    }
    }
 
 
  /* If we found either a type binding or a value binding, create a
  /* If we found either a type binding or a value binding, create a
     new binding object.  */
     new binding object.  */
  if (type_binding || value_binding)
  if (type_binding || value_binding)
    {
    {
      binding = new_class_binding (name,
      binding = new_class_binding (name,
                                   value_binding,
                                   value_binding,
                                   type_binding,
                                   type_binding,
                                   scope);
                                   scope);
      /* This is a class-scope binding, not a block-scope binding.  */
      /* This is a class-scope binding, not a block-scope binding.  */
      LOCAL_BINDING_P (binding) = 0;
      LOCAL_BINDING_P (binding) = 0;
      set_inherited_value_binding_p (binding, value_binding, class_type);
      set_inherited_value_binding_p (binding, value_binding, class_type);
    }
    }
  else
  else
    binding = NULL;
    binding = NULL;
 
 
  return binding;
  return binding;
}
}
 
 
/* Make the declaration(s) of X appear in CLASS scope under the name
/* Make the declaration(s) of X appear in CLASS scope under the name
   NAME.  Returns true if the binding is valid.  */
   NAME.  Returns true if the binding is valid.  */
 
 
bool
bool
push_class_level_binding (tree name, tree x)
push_class_level_binding (tree name, tree x)
{
{
  cxx_binding *binding;
  cxx_binding *binding;
  tree decl = x;
  tree decl = x;
  bool ok;
  bool ok;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  /* The class_binding_level will be NULL if x is a template
  /* The class_binding_level will be NULL if x is a template
     parameter name in a member template.  */
     parameter name in a member template.  */
  if (!class_binding_level)
  if (!class_binding_level)
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
 
 
  if (name == error_mark_node)
  if (name == error_mark_node)
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
 
 
  /* Check for invalid member names.  */
  /* Check for invalid member names.  */
  gcc_assert (TYPE_BEING_DEFINED (current_class_type));
  gcc_assert (TYPE_BEING_DEFINED (current_class_type));
  /* Check that we're pushing into the right binding level.  */
  /* Check that we're pushing into the right binding level.  */
  gcc_assert (current_class_type == class_binding_level->this_entity);
  gcc_assert (current_class_type == class_binding_level->this_entity);
 
 
  /* We could have been passed a tree list if this is an ambiguous
  /* We could have been passed a tree list if this is an ambiguous
     declaration. If so, pull the declaration out because
     declaration. If so, pull the declaration out because
     check_template_shadow will not handle a TREE_LIST.  */
     check_template_shadow will not handle a TREE_LIST.  */
  if (TREE_CODE (decl) == TREE_LIST
  if (TREE_CODE (decl) == TREE_LIST
      && TREE_TYPE (decl) == error_mark_node)
      && TREE_TYPE (decl) == error_mark_node)
    decl = TREE_VALUE (decl);
    decl = TREE_VALUE (decl);
 
 
  if (!check_template_shadow (decl))
  if (!check_template_shadow (decl))
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
 
 
  /* [class.mem]
  /* [class.mem]
 
 
     If T is the name of a class, then each of the following shall
     If T is the name of a class, then each of the following shall
     have a name different from T:
     have a name different from T:
 
 
     -- every static data member of class T;
     -- every static data member of class T;
 
 
     -- every member of class T that is itself a type;
     -- every member of class T that is itself a type;
 
 
     -- every enumerator of every member of class T that is an
     -- every enumerator of every member of class T that is an
        enumerated type;
        enumerated type;
 
 
     -- every member of every anonymous union that is a member of
     -- every member of every anonymous union that is a member of
        class T.
        class T.
 
 
     (Non-static data members were also forbidden to have the same
     (Non-static data members were also forbidden to have the same
     name as T until TC1.)  */
     name as T until TC1.)  */
  if ((TREE_CODE (x) == VAR_DECL
  if ((TREE_CODE (x) == VAR_DECL
       || TREE_CODE (x) == CONST_DECL
       || TREE_CODE (x) == CONST_DECL
       || (TREE_CODE (x) == TYPE_DECL
       || (TREE_CODE (x) == TYPE_DECL
           && !DECL_SELF_REFERENCE_P (x))
           && !DECL_SELF_REFERENCE_P (x))
       /* A data member of an anonymous union.  */
       /* A data member of an anonymous union.  */
       || (TREE_CODE (x) == FIELD_DECL
       || (TREE_CODE (x) == FIELD_DECL
           && DECL_CONTEXT (x) != current_class_type))
           && DECL_CONTEXT (x) != current_class_type))
      && DECL_NAME (x) == constructor_name (current_class_type))
      && DECL_NAME (x) == constructor_name (current_class_type))
    {
    {
      tree scope = context_for_name_lookup (x);
      tree scope = context_for_name_lookup (x);
      if (TYPE_P (scope) && same_type_p (scope, current_class_type))
      if (TYPE_P (scope) && same_type_p (scope, current_class_type))
        {
        {
          error ("%qD has the same name as the class in which it is "
          error ("%qD has the same name as the class in which it is "
                 "declared",
                 "declared",
                 x);
                 x);
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
        }
        }
    }
    }
 
 
  /* Get the current binding for NAME in this class, if any.  */
  /* Get the current binding for NAME in this class, if any.  */
  binding = IDENTIFIER_BINDING (name);
  binding = IDENTIFIER_BINDING (name);
  if (!binding || binding->scope != class_binding_level)
  if (!binding || binding->scope != class_binding_level)
    {
    {
      binding = get_class_binding (name, class_binding_level);
      binding = get_class_binding (name, class_binding_level);
      /* If a new binding was created, put it at the front of the
      /* If a new binding was created, put it at the front of the
         IDENTIFIER_BINDING list.  */
         IDENTIFIER_BINDING list.  */
      if (binding)
      if (binding)
        {
        {
          binding->previous = IDENTIFIER_BINDING (name);
          binding->previous = IDENTIFIER_BINDING (name);
          IDENTIFIER_BINDING (name) = binding;
          IDENTIFIER_BINDING (name) = binding;
        }
        }
    }
    }
 
 
  /* If there is already a binding, then we may need to update the
  /* If there is already a binding, then we may need to update the
     current value.  */
     current value.  */
  if (binding && binding->value)
  if (binding && binding->value)
    {
    {
      tree bval = binding->value;
      tree bval = binding->value;
      tree old_decl = NULL_TREE;
      tree old_decl = NULL_TREE;
 
 
      if (INHERITED_VALUE_BINDING_P (binding))
      if (INHERITED_VALUE_BINDING_P (binding))
        {
        {
          /* If the old binding was from a base class, and was for a
          /* If the old binding was from a base class, and was for a
             tag name, slide it over to make room for the new binding.
             tag name, slide it over to make room for the new binding.
             The old binding is still visible if explicitly qualified
             The old binding is still visible if explicitly qualified
             with a class-key.  */
             with a class-key.  */
          if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
          if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
              && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
              && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
            {
            {
              old_decl = binding->type;
              old_decl = binding->type;
              binding->type = bval;
              binding->type = bval;
              binding->value = NULL_TREE;
              binding->value = NULL_TREE;
              INHERITED_VALUE_BINDING_P (binding) = 0;
              INHERITED_VALUE_BINDING_P (binding) = 0;
            }
            }
          else
          else
            {
            {
              old_decl = bval;
              old_decl = bval;
              /* Any inherited type declaration is hidden by the type
              /* Any inherited type declaration is hidden by the type
                 declaration in the derived class.  */
                 declaration in the derived class.  */
              if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
              if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
                binding->type = NULL_TREE;
                binding->type = NULL_TREE;
            }
            }
        }
        }
      else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval))
      else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval))
        old_decl = bval;
        old_decl = bval;
      else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL)
      else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL)
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
      else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval))
      else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval))
        old_decl = bval;
        old_decl = bval;
      else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x))
      else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x))
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
 
 
      if (old_decl && binding->scope == class_binding_level)
      if (old_decl && binding->scope == class_binding_level)
        {
        {
          binding->value = x;
          binding->value = x;
          /* It is always safe to clear INHERITED_VALUE_BINDING_P
          /* It is always safe to clear INHERITED_VALUE_BINDING_P
             here.  This function is only used to register bindings
             here.  This function is only used to register bindings
             from with the class definition itself.  */
             from with the class definition itself.  */
          INHERITED_VALUE_BINDING_P (binding) = 0;
          INHERITED_VALUE_BINDING_P (binding) = 0;
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
        }
        }
    }
    }
 
 
  /* Note that we declared this value so that we can issue an error if
  /* Note that we declared this value so that we can issue an error if
     this is an invalid redeclaration of a name already used for some
     this is an invalid redeclaration of a name already used for some
     other purpose.  */
     other purpose.  */
  note_name_declared_in_class (name, decl);
  note_name_declared_in_class (name, decl);
 
 
  /* If we didn't replace an existing binding, put the binding on the
  /* If we didn't replace an existing binding, put the binding on the
     stack of bindings for the identifier, and update the shadowed
     stack of bindings for the identifier, and update the shadowed
     list.  */
     list.  */
  if (binding && binding->scope == class_binding_level)
  if (binding && binding->scope == class_binding_level)
    /* Supplement the existing binding.  */
    /* Supplement the existing binding.  */
    ok = supplement_binding (binding, decl);
    ok = supplement_binding (binding, decl);
  else
  else
    {
    {
      /* Create a new binding.  */
      /* Create a new binding.  */
      push_binding (name, decl, class_binding_level);
      push_binding (name, decl, class_binding_level);
      ok = true;
      ok = true;
    }
    }
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
}
}
 
 
/* Process "using SCOPE::NAME" in a class scope.  Return the
/* Process "using SCOPE::NAME" in a class scope.  Return the
   USING_DECL created.  */
   USING_DECL created.  */
 
 
tree
tree
do_class_using_decl (tree scope, tree name)
do_class_using_decl (tree scope, tree name)
{
{
  /* The USING_DECL returned by this function.  */
  /* The USING_DECL returned by this function.  */
  tree value;
  tree value;
  /* The declaration (or declarations) name by this using
  /* The declaration (or declarations) name by this using
     declaration.  NULL if we are in a template and cannot figure out
     declaration.  NULL if we are in a template and cannot figure out
     what has been named.  */
     what has been named.  */
  tree decl;
  tree decl;
  /* True if SCOPE is a dependent type.  */
  /* True if SCOPE is a dependent type.  */
  bool scope_dependent_p;
  bool scope_dependent_p;
  /* True if SCOPE::NAME is dependent.  */
  /* True if SCOPE::NAME is dependent.  */
  bool name_dependent_p;
  bool name_dependent_p;
  /* True if any of the bases of CURRENT_CLASS_TYPE are dependent.  */
  /* True if any of the bases of CURRENT_CLASS_TYPE are dependent.  */
  bool bases_dependent_p;
  bool bases_dependent_p;
  tree binfo;
  tree binfo;
  tree base_binfo;
  tree base_binfo;
  int i;
  int i;
 
 
  if (name == error_mark_node)
  if (name == error_mark_node)
    return NULL_TREE;
    return NULL_TREE;
 
 
  if (!scope || !TYPE_P (scope))
  if (!scope || !TYPE_P (scope))
    {
    {
      error ("using-declaration for non-member at class scope");
      error ("using-declaration for non-member at class scope");
      return NULL_TREE;
      return NULL_TREE;
    }
    }
 
 
  /* Make sure the name is not invalid */
  /* Make sure the name is not invalid */
  if (TREE_CODE (name) == BIT_NOT_EXPR)
  if (TREE_CODE (name) == BIT_NOT_EXPR)
    {
    {
      error ("%<%T::%D%> names destructor", scope, name);
      error ("%<%T::%D%> names destructor", scope, name);
      return NULL_TREE;
      return NULL_TREE;
    }
    }
  if (MAYBE_CLASS_TYPE_P (scope) && constructor_name_p (name, scope))
  if (MAYBE_CLASS_TYPE_P (scope) && constructor_name_p (name, scope))
    {
    {
      error ("%<%T::%D%> names constructor", scope, name);
      error ("%<%T::%D%> names constructor", scope, name);
      return NULL_TREE;
      return NULL_TREE;
    }
    }
  if (constructor_name_p (name, current_class_type))
  if (constructor_name_p (name, current_class_type))
    {
    {
      error ("%<%T::%D%> names constructor in %qT",
      error ("%<%T::%D%> names constructor in %qT",
             scope, name, current_class_type);
             scope, name, current_class_type);
      return NULL_TREE;
      return NULL_TREE;
    }
    }
 
 
  scope_dependent_p = dependent_type_p (scope);
  scope_dependent_p = dependent_type_p (scope);
  name_dependent_p = (scope_dependent_p
  name_dependent_p = (scope_dependent_p
                      || (IDENTIFIER_TYPENAME_P (name)
                      || (IDENTIFIER_TYPENAME_P (name)
                          && dependent_type_p (TREE_TYPE (name))));
                          && dependent_type_p (TREE_TYPE (name))));
 
 
  bases_dependent_p = false;
  bases_dependent_p = false;
  if (processing_template_decl)
  if (processing_template_decl)
    for (binfo = TYPE_BINFO (current_class_type), i = 0;
    for (binfo = TYPE_BINFO (current_class_type), i = 0;
         BINFO_BASE_ITERATE (binfo, i, base_binfo);
         BINFO_BASE_ITERATE (binfo, i, base_binfo);
         i++)
         i++)
      if (dependent_type_p (TREE_TYPE (base_binfo)))
      if (dependent_type_p (TREE_TYPE (base_binfo)))
        {
        {
          bases_dependent_p = true;
          bases_dependent_p = true;
          break;
          break;
        }
        }
 
 
  decl = NULL_TREE;
  decl = NULL_TREE;
 
 
  /* From [namespace.udecl]:
  /* From [namespace.udecl]:
 
 
       A using-declaration used as a member-declaration shall refer to a
       A using-declaration used as a member-declaration shall refer to a
       member of a base class of the class being defined.
       member of a base class of the class being defined.
 
 
     In general, we cannot check this constraint in a template because
     In general, we cannot check this constraint in a template because
     we do not know the entire set of base classes of the current
     we do not know the entire set of base classes of the current
     class type.  However, if all of the base classes are
     class type.  However, if all of the base classes are
     non-dependent, then we can avoid delaying the check until
     non-dependent, then we can avoid delaying the check until
     instantiation.  */
     instantiation.  */
  if (!scope_dependent_p)
  if (!scope_dependent_p)
    {
    {
      base_kind b_kind;
      base_kind b_kind;
      binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
      binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
      if (b_kind < bk_proper_base)
      if (b_kind < bk_proper_base)
        {
        {
          if (!bases_dependent_p)
          if (!bases_dependent_p)
            {
            {
              error_not_base_type (scope, current_class_type);
              error_not_base_type (scope, current_class_type);
              return NULL_TREE;
              return NULL_TREE;
            }
            }
        }
        }
      else if (!name_dependent_p)
      else if (!name_dependent_p)
        {
        {
          decl = lookup_member (binfo, name, 0, false);
          decl = lookup_member (binfo, name, 0, false);
          if (!decl)
          if (!decl)
            {
            {
              error ("no members matching %<%T::%D%> in %q#T", scope, name,
              error ("no members matching %<%T::%D%> in %q#T", scope, name,
                     scope);
                     scope);
              return NULL_TREE;
              return NULL_TREE;
            }
            }
          /* The binfo from which the functions came does not matter.  */
          /* The binfo from which the functions came does not matter.  */
          if (BASELINK_P (decl))
          if (BASELINK_P (decl))
            decl = BASELINK_FUNCTIONS (decl);
            decl = BASELINK_FUNCTIONS (decl);
        }
        }
   }
   }
 
 
  value = build_lang_decl (USING_DECL, name, NULL_TREE);
  value = build_lang_decl (USING_DECL, name, NULL_TREE);
  USING_DECL_DECLS (value) = decl;
  USING_DECL_DECLS (value) = decl;
  USING_DECL_SCOPE (value) = scope;
  USING_DECL_SCOPE (value) = scope;
  DECL_DEPENDENT_P (value) = !decl;
  DECL_DEPENDENT_P (value) = !decl;
 
 
  return value;
  return value;
}
}
 
 


/* Return the binding value for name in scope.  */
/* Return the binding value for name in scope.  */
 
 
tree
tree
namespace_binding (tree name, tree scope)
namespace_binding (tree name, tree scope)
{
{
  cxx_binding *binding;
  cxx_binding *binding;
 
 
  if (scope == NULL)
  if (scope == NULL)
    scope = global_namespace;
    scope = global_namespace;
  else
  else
    /* Unnecessary for the global namespace because it can't be an alias. */
    /* Unnecessary for the global namespace because it can't be an alias. */
    scope = ORIGINAL_NAMESPACE (scope);
    scope = ORIGINAL_NAMESPACE (scope);
 
 
  binding = cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
  binding = cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
 
 
  return binding ? binding->value : NULL_TREE;
  return binding ? binding->value : NULL_TREE;
}
}
 
 
/* Set the binding value for name in scope.  */
/* Set the binding value for name in scope.  */
 
 
void
void
set_namespace_binding (tree name, tree scope, tree val)
set_namespace_binding (tree name, tree scope, tree val)
{
{
  cxx_binding *b;
  cxx_binding *b;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  if (scope == NULL_TREE)
  if (scope == NULL_TREE)
    scope = global_namespace;
    scope = global_namespace;
  b = binding_for_name (NAMESPACE_LEVEL (scope), name);
  b = binding_for_name (NAMESPACE_LEVEL (scope), name);
  if (!b->value || TREE_CODE (val) == OVERLOAD || val == error_mark_node)
  if (!b->value || TREE_CODE (val) == OVERLOAD || val == error_mark_node)
    b->value = val;
    b->value = val;
  else
  else
    supplement_binding (b, val);
    supplement_binding (b, val);
  timevar_pop (TV_NAME_LOOKUP);
  timevar_pop (TV_NAME_LOOKUP);
}
}
 
 
/* Set the context of a declaration to scope. Complain if we are not
/* Set the context of a declaration to scope. Complain if we are not
   outside scope.  */
   outside scope.  */
 
 
void
void
set_decl_namespace (tree decl, tree scope, bool friendp)
set_decl_namespace (tree decl, tree scope, bool friendp)
{
{
  tree old;
  tree old;
 
 
  /* Get rid of namespace aliases.  */
  /* Get rid of namespace aliases.  */
  scope = ORIGINAL_NAMESPACE (scope);
  scope = ORIGINAL_NAMESPACE (scope);
 
 
  /* It is ok for friends to be qualified in parallel space.  */
  /* It is ok for friends to be qualified in parallel space.  */
  if (!friendp && !is_ancestor (current_namespace, scope))
  if (!friendp && !is_ancestor (current_namespace, scope))
    error ("declaration of %qD not in a namespace surrounding %qD",
    error ("declaration of %qD not in a namespace surrounding %qD",
           decl, scope);
           decl, scope);
  DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
  DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
 
 
  /* Writing "int N::i" to declare a variable within "N" is invalid.  */
  /* Writing "int N::i" to declare a variable within "N" is invalid.  */
  if (scope == current_namespace)
  if (scope == current_namespace)
    {
    {
      if (at_namespace_scope_p ())
      if (at_namespace_scope_p ())
        error ("explicit qualification in declaration of %qD",
        error ("explicit qualification in declaration of %qD",
               decl);
               decl);
      return;
      return;
    }
    }
 
 
  /* See whether this has been declared in the namespace.  */
  /* See whether this has been declared in the namespace.  */
  old = lookup_qualified_name (scope, DECL_NAME (decl), false, true);
  old = lookup_qualified_name (scope, DECL_NAME (decl), false, true);
  if (old == error_mark_node)
  if (old == error_mark_node)
    /* No old declaration at all.  */
    /* No old declaration at all.  */
    goto complain;
    goto complain;
  /* If it's a TREE_LIST, the result of the lookup was ambiguous.  */
  /* If it's a TREE_LIST, the result of the lookup was ambiguous.  */
  if (TREE_CODE (old) == TREE_LIST)
  if (TREE_CODE (old) == TREE_LIST)
    {
    {
      error ("reference to %qD is ambiguous", decl);
      error ("reference to %qD is ambiguous", decl);
      print_candidates (old);
      print_candidates (old);
      return;
      return;
    }
    }
  if (!is_overloaded_fn (decl))
  if (!is_overloaded_fn (decl))
    {
    {
      /* We might have found OLD in an inline namespace inside SCOPE.  */
      /* We might have found OLD in an inline namespace inside SCOPE.  */
      if (TREE_CODE (decl) == TREE_CODE (old))
      if (TREE_CODE (decl) == TREE_CODE (old))
        DECL_CONTEXT (decl) = DECL_CONTEXT (old);
        DECL_CONTEXT (decl) = DECL_CONTEXT (old);
      /* Don't compare non-function decls with decls_match here, since
      /* Don't compare non-function decls with decls_match here, since
         it can't check for the correct constness at this
         it can't check for the correct constness at this
         point. pushdecl will find those errors later.  */
         point. pushdecl will find those errors later.  */
      return;
      return;
    }
    }
  /* Since decl is a function, old should contain a function decl.  */
  /* Since decl is a function, old should contain a function decl.  */
  if (!is_overloaded_fn (old))
  if (!is_overloaded_fn (old))
    goto complain;
    goto complain;
  /* A template can be explicitly specialized in any namespace.  */
  /* A template can be explicitly specialized in any namespace.  */
  if (processing_explicit_instantiation)
  if (processing_explicit_instantiation)
    return;
    return;
  if (processing_template_decl || processing_specialization)
  if (processing_template_decl || processing_specialization)
    /* We have not yet called push_template_decl to turn a
    /* We have not yet called push_template_decl to turn a
       FUNCTION_DECL into a TEMPLATE_DECL, so the declarations won't
       FUNCTION_DECL into a TEMPLATE_DECL, so the declarations won't
       match.  But, we'll check later, when we construct the
       match.  But, we'll check later, when we construct the
       template.  */
       template.  */
    return;
    return;
  /* Instantiations or specializations of templates may be declared as
  /* Instantiations or specializations of templates may be declared as
     friends in any namespace.  */
     friends in any namespace.  */
  if (friendp && DECL_USE_TEMPLATE (decl))
  if (friendp && DECL_USE_TEMPLATE (decl))
    return;
    return;
  if (is_overloaded_fn (old))
  if (is_overloaded_fn (old))
    {
    {
      tree found = NULL_TREE;
      tree found = NULL_TREE;
      tree elt = old;
      tree elt = old;
      for (; elt; elt = OVL_NEXT (elt))
      for (; elt; elt = OVL_NEXT (elt))
        {
        {
          tree ofn = OVL_CURRENT (elt);
          tree ofn = OVL_CURRENT (elt);
          /* Adjust DECL_CONTEXT first so decls_match will return true
          /* Adjust DECL_CONTEXT first so decls_match will return true
             if DECL will match a declaration in an inline namespace.  */
             if DECL will match a declaration in an inline namespace.  */
          DECL_CONTEXT (decl) = DECL_CONTEXT (ofn);
          DECL_CONTEXT (decl) = DECL_CONTEXT (ofn);
          if (decls_match (decl, ofn))
          if (decls_match (decl, ofn))
            {
            {
              if (found && !decls_match (found, ofn))
              if (found && !decls_match (found, ofn))
                {
                {
                  DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
                  DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
                  error ("reference to %qD is ambiguous", decl);
                  error ("reference to %qD is ambiguous", decl);
                  print_candidates (old);
                  print_candidates (old);
                  return;
                  return;
                }
                }
              found = ofn;
              found = ofn;
            }
            }
        }
        }
      if (found)
      if (found)
        {
        {
          if (!is_associated_namespace (scope, CP_DECL_CONTEXT (found)))
          if (!is_associated_namespace (scope, CP_DECL_CONTEXT (found)))
            goto complain;
            goto complain;
          DECL_CONTEXT (decl) = DECL_CONTEXT (found);
          DECL_CONTEXT (decl) = DECL_CONTEXT (found);
          return;
          return;
        }
        }
    }
    }
  else
  else
    {
    {
      DECL_CONTEXT (decl) = DECL_CONTEXT (old);
      DECL_CONTEXT (decl) = DECL_CONTEXT (old);
      if (decls_match (decl, old))
      if (decls_match (decl, old))
        return;
        return;
    }
    }
 
 
  /* It didn't work, go back to the explicit scope.  */
  /* It didn't work, go back to the explicit scope.  */
  DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
  DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
 complain:
 complain:
  error ("%qD should have been declared inside %qD", decl, scope);
  error ("%qD should have been declared inside %qD", decl, scope);
}
}
 
 
/* Return the namespace where the current declaration is declared.  */
/* Return the namespace where the current declaration is declared.  */
 
 
static tree
static tree
current_decl_namespace (void)
current_decl_namespace (void)
{
{
  tree result;
  tree result;
  /* If we have been pushed into a different namespace, use it.  */
  /* If we have been pushed into a different namespace, use it.  */
  if (decl_namespace_list)
  if (decl_namespace_list)
    return TREE_PURPOSE (decl_namespace_list);
    return TREE_PURPOSE (decl_namespace_list);
 
 
  if (current_class_type)
  if (current_class_type)
    result = decl_namespace_context (current_class_type);
    result = decl_namespace_context (current_class_type);
  else if (current_function_decl)
  else if (current_function_decl)
    result = decl_namespace_context (current_function_decl);
    result = decl_namespace_context (current_function_decl);
  else
  else
    result = current_namespace;
    result = current_namespace;
  return result;
  return result;
}
}
 
 
/* Process any ATTRIBUTES on a namespace definition.  Currently only
/* Process any ATTRIBUTES on a namespace definition.  Currently only
   attribute visibility is meaningful, which is a property of the syntactic
   attribute visibility is meaningful, which is a property of the syntactic
   block rather than the namespace as a whole, so we don't touch the
   block rather than the namespace as a whole, so we don't touch the
   NAMESPACE_DECL at all.  Returns true if attribute visibility is seen.  */
   NAMESPACE_DECL at all.  Returns true if attribute visibility is seen.  */
 
 
bool
bool
handle_namespace_attrs (tree ns, tree attributes)
handle_namespace_attrs (tree ns, tree attributes)
{
{
  tree d;
  tree d;
  bool saw_vis = false;
  bool saw_vis = false;
 
 
  for (d = attributes; d; d = TREE_CHAIN (d))
  for (d = attributes; d; d = TREE_CHAIN (d))
    {
    {
      tree name = TREE_PURPOSE (d);
      tree name = TREE_PURPOSE (d);
      tree args = TREE_VALUE (d);
      tree args = TREE_VALUE (d);
 
 
#ifdef HANDLE_PRAGMA_VISIBILITY
#ifdef HANDLE_PRAGMA_VISIBILITY
      if (is_attribute_p ("visibility", name))
      if (is_attribute_p ("visibility", name))
        {
        {
          tree x = args ? TREE_VALUE (args) : NULL_TREE;
          tree x = args ? TREE_VALUE (args) : NULL_TREE;
          if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args))
          if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args))
            {
            {
              warning (OPT_Wattributes,
              warning (OPT_Wattributes,
                       "%qD attribute requires a single NTBS argument",
                       "%qD attribute requires a single NTBS argument",
                       name);
                       name);
              continue;
              continue;
            }
            }
 
 
          if (!TREE_PUBLIC (ns))
          if (!TREE_PUBLIC (ns))
            warning (OPT_Wattributes,
            warning (OPT_Wattributes,
                     "%qD attribute is meaningless since members of the "
                     "%qD attribute is meaningless since members of the "
                     "anonymous namespace get local symbols", name);
                     "anonymous namespace get local symbols", name);
 
 
          push_visibility (TREE_STRING_POINTER (x), 1);
          push_visibility (TREE_STRING_POINTER (x), 1);
          saw_vis = true;
          saw_vis = true;
        }
        }
      else
      else
#endif
#endif
        {
        {
          warning (OPT_Wattributes, "%qD attribute directive ignored",
          warning (OPT_Wattributes, "%qD attribute directive ignored",
                   name);
                   name);
          continue;
          continue;
        }
        }
    }
    }
 
 
  return saw_vis;
  return saw_vis;
}
}
 
 
/* Push into the scope of the NAME namespace.  If NAME is NULL_TREE, then we
/* 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.  */
   select a name that is unique to this compilation unit.  */
 
 
void
void
push_namespace (tree name)
push_namespace (tree name)
{
{
  tree d = NULL_TREE;
  tree d = NULL_TREE;
  int need_new = 1;
  int need_new = 1;
  int implicit_use = 0;
  int implicit_use = 0;
  bool anon = !name;
  bool anon = !name;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
 
 
  /* We should not get here if the global_namespace is not yet constructed
  /* We should not get here if the global_namespace is not yet constructed
     nor if NAME designates the global namespace:  The global scope is
     nor if NAME designates the global namespace:  The global scope is
     constructed elsewhere.  */
     constructed elsewhere.  */
  gcc_assert (global_namespace != NULL && name != global_scope_name);
  gcc_assert (global_namespace != NULL && name != global_scope_name);
 
 
  if (anon)
  if (anon)
    {
    {
      name = get_anonymous_namespace_name();
      name = get_anonymous_namespace_name();
      d = IDENTIFIER_NAMESPACE_VALUE (name);
      d = IDENTIFIER_NAMESPACE_VALUE (name);
      if (d)
      if (d)
        /* Reopening anonymous namespace.  */
        /* Reopening anonymous namespace.  */
        need_new = 0;
        need_new = 0;
      implicit_use = 1;
      implicit_use = 1;
    }
    }
  else
  else
    {
    {
      /* Check whether this is an extended namespace definition.  */
      /* Check whether this is an extended namespace definition.  */
      d = IDENTIFIER_NAMESPACE_VALUE (name);
      d = IDENTIFIER_NAMESPACE_VALUE (name);
      if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
      if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
        {
        {
          need_new = 0;
          need_new = 0;
          if (DECL_NAMESPACE_ALIAS (d))
          if (DECL_NAMESPACE_ALIAS (d))
            {
            {
              error ("namespace alias %qD not allowed here, assuming %qD",
              error ("namespace alias %qD not allowed here, assuming %qD",
                     d, DECL_NAMESPACE_ALIAS (d));
                     d, DECL_NAMESPACE_ALIAS (d));
              d = DECL_NAMESPACE_ALIAS (d);
              d = DECL_NAMESPACE_ALIAS (d);
            }
            }
        }
        }
    }
    }
 
 
  if (need_new)
  if (need_new)
    {
    {
      /* Make a new namespace, binding the name to it.  */
      /* Make a new namespace, binding the name to it.  */
      d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
      d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
      DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
      DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
      /* The name of this namespace is not visible to other translation
      /* The name of this namespace is not visible to other translation
         units if it is an anonymous namespace or member thereof.  */
         units if it is an anonymous namespace or member thereof.  */
      if (anon || decl_anon_ns_mem_p (current_namespace))
      if (anon || decl_anon_ns_mem_p (current_namespace))
        TREE_PUBLIC (d) = 0;
        TREE_PUBLIC (d) = 0;
      else
      else
        TREE_PUBLIC (d) = 1;
        TREE_PUBLIC (d) = 1;
      pushdecl (d);
      pushdecl (d);
      if (anon)
      if (anon)
        {
        {
          /* Clear DECL_NAME for the benefit of debugging back ends.  */
          /* Clear DECL_NAME for the benefit of debugging back ends.  */
          SET_DECL_ASSEMBLER_NAME (d, name);
          SET_DECL_ASSEMBLER_NAME (d, name);
          DECL_NAME (d) = NULL_TREE;
          DECL_NAME (d) = NULL_TREE;
        }
        }
      begin_scope (sk_namespace, d);
      begin_scope (sk_namespace, d);
    }
    }
  else
  else
    resume_scope (NAMESPACE_LEVEL (d));
    resume_scope (NAMESPACE_LEVEL (d));
 
 
  if (implicit_use)
  if (implicit_use)
    do_using_directive (d);
    do_using_directive (d);
  /* Enter the name space.  */
  /* Enter the name space.  */
  current_namespace = d;
  current_namespace = d;
 
 
  timevar_pop (TV_NAME_LOOKUP);
  timevar_pop (TV_NAME_LOOKUP);
}
}
 
 
/* Pop from the scope of the current namespace.  */
/* Pop from the scope of the current namespace.  */
 
 
void
void
pop_namespace (void)
pop_namespace (void)
{
{
  gcc_assert (current_namespace != global_namespace);
  gcc_assert (current_namespace != global_namespace);
  current_namespace = CP_DECL_CONTEXT (current_namespace);
  current_namespace = CP_DECL_CONTEXT (current_namespace);
  /* The binding level is not popped, as it might be re-opened later.  */
  /* The binding level is not popped, as it might be re-opened later.  */
  leave_scope ();
  leave_scope ();
}
}
 
 
/* Push into the scope of the namespace NS, even if it is deeply
/* Push into the scope of the namespace NS, even if it is deeply
   nested within another namespace.  */
   nested within another namespace.  */
 
 
void
void
push_nested_namespace (tree ns)
push_nested_namespace (tree ns)
{
{
  if (ns == global_namespace)
  if (ns == global_namespace)
    push_to_top_level ();
    push_to_top_level ();
  else
  else
    {
    {
      push_nested_namespace (CP_DECL_CONTEXT (ns));
      push_nested_namespace (CP_DECL_CONTEXT (ns));
      push_namespace (DECL_NAME (ns));
      push_namespace (DECL_NAME (ns));
    }
    }
}
}
 
 
/* Pop back from the scope of the namespace NS, which was previously
/* Pop back from the scope of the namespace NS, which was previously
   entered with push_nested_namespace.  */
   entered with push_nested_namespace.  */
 
 
void
void
pop_nested_namespace (tree ns)
pop_nested_namespace (tree ns)
{
{
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  while (ns != global_namespace)
  while (ns != global_namespace)
    {
    {
      pop_namespace ();
      pop_namespace ();
      ns = CP_DECL_CONTEXT (ns);
      ns = CP_DECL_CONTEXT (ns);
    }
    }
 
 
  pop_from_top_level ();
  pop_from_top_level ();
  timevar_pop (TV_NAME_LOOKUP);
  timevar_pop (TV_NAME_LOOKUP);
}
}
 
 
/* Temporarily set the namespace for the current declaration.  */
/* Temporarily set the namespace for the current declaration.  */
 
 
void
void
push_decl_namespace (tree decl)
push_decl_namespace (tree decl)
{
{
  if (TREE_CODE (decl) != NAMESPACE_DECL)
  if (TREE_CODE (decl) != NAMESPACE_DECL)
    decl = decl_namespace_context (decl);
    decl = decl_namespace_context (decl);
  decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
  decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
                                   NULL_TREE, decl_namespace_list);
                                   NULL_TREE, decl_namespace_list);
}
}
 
 
/* [namespace.memdef]/2 */
/* [namespace.memdef]/2 */
 
 
void
void
pop_decl_namespace (void)
pop_decl_namespace (void)
{
{
  decl_namespace_list = TREE_CHAIN (decl_namespace_list);
  decl_namespace_list = TREE_CHAIN (decl_namespace_list);
}
}
 
 
/* Return the namespace that is the common ancestor
/* Return the namespace that is the common ancestor
   of two given namespaces.  */
   of two given namespaces.  */
 
 
static tree
static tree
namespace_ancestor (tree ns1, tree ns2)
namespace_ancestor (tree ns1, tree ns2)
{
{
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  if (is_ancestor (ns1, ns2))
  if (is_ancestor (ns1, ns2))
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ns1);
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ns1);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
                          namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2));
                          namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2));
}
}
 
 
/* Process a namespace-alias declaration.  */
/* Process a namespace-alias declaration.  */
 
 
void
void
do_namespace_alias (tree alias, tree name_space)
do_namespace_alias (tree alias, tree name_space)
{
{
  if (name_space == error_mark_node)
  if (name_space == error_mark_node)
    return;
    return;
 
 
  gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
  gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
 
 
  name_space = ORIGINAL_NAMESPACE (name_space);
  name_space = ORIGINAL_NAMESPACE (name_space);
 
 
  /* Build the alias.  */
  /* Build the alias.  */
  alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
  alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
  DECL_NAMESPACE_ALIAS (alias) = name_space;
  DECL_NAMESPACE_ALIAS (alias) = name_space;
  DECL_EXTERNAL (alias) = 1;
  DECL_EXTERNAL (alias) = 1;
  DECL_CONTEXT (alias) = FROB_CONTEXT (current_scope ());
  DECL_CONTEXT (alias) = FROB_CONTEXT (current_scope ());
  pushdecl (alias);
  pushdecl (alias);
 
 
  /* Emit debug info for namespace alias.  */
  /* Emit debug info for namespace alias.  */
  if (!building_stmt_tree ())
  if (!building_stmt_tree ())
    (*debug_hooks->global_decl) (alias);
    (*debug_hooks->global_decl) (alias);
}
}
 
 
/* Like pushdecl, only it places X in the current namespace,
/* Like pushdecl, only it places X in the current namespace,
   if appropriate.  */
   if appropriate.  */
 
 
tree
tree
pushdecl_namespace_level (tree x, bool is_friend)
pushdecl_namespace_level (tree x, bool is_friend)
{
{
  struct cp_binding_level *b = current_binding_level;
  struct cp_binding_level *b = current_binding_level;
  tree t;
  tree t;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace), is_friend);
  t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace), is_friend);
 
 
  /* Now, the type_shadowed stack may screw us.  Munge it so it does
  /* Now, the type_shadowed stack may screw us.  Munge it so it does
     what we want.  */
     what we want.  */
  if (TREE_CODE (t) == TYPE_DECL)
  if (TREE_CODE (t) == TYPE_DECL)
    {
    {
      tree name = DECL_NAME (t);
      tree name = DECL_NAME (t);
      tree newval;
      tree newval;
      tree *ptr = (tree *)0;
      tree *ptr = (tree *)0;
      for (; !global_scope_p (b); b = b->level_chain)
      for (; !global_scope_p (b); b = b->level_chain)
        {
        {
          tree shadowed = b->type_shadowed;
          tree shadowed = b->type_shadowed;
          for (; shadowed; shadowed = TREE_CHAIN (shadowed))
          for (; shadowed; shadowed = TREE_CHAIN (shadowed))
            if (TREE_PURPOSE (shadowed) == name)
            if (TREE_PURPOSE (shadowed) == name)
              {
              {
                ptr = &TREE_VALUE (shadowed);
                ptr = &TREE_VALUE (shadowed);
                /* Can't break out of the loop here because sometimes
                /* Can't break out of the loop here because sometimes
                   a binding level will have duplicate bindings for
                   a binding level will have duplicate bindings for
                   PT names.  It's gross, but I haven't time to fix it.  */
                   PT names.  It's gross, but I haven't time to fix it.  */
              }
              }
        }
        }
      newval = TREE_TYPE (t);
      newval = TREE_TYPE (t);
      if (ptr == (tree *)0)
      if (ptr == (tree *)0)
        {
        {
          /* @@ This shouldn't be needed.  My test case "zstring.cc" trips
          /* @@ This shouldn't be needed.  My test case "zstring.cc" trips
             up here if this is changed to an assertion.  --KR  */
             up here if this is changed to an assertion.  --KR  */
          SET_IDENTIFIER_TYPE_VALUE (name, t);
          SET_IDENTIFIER_TYPE_VALUE (name, t);
        }
        }
      else
      else
        {
        {
          *ptr = newval;
          *ptr = newval;
        }
        }
    }
    }
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
}
 
 
/* Insert USED into the using list of USER. Set INDIRECT_flag if this
/* Insert USED into the using list of USER. Set INDIRECT_flag if this
   directive is not directly from the source. Also find the common
   directive is not directly from the source. Also find the common
   ancestor and let our users know about the new namespace */
   ancestor and let our users know about the new namespace */
static void
static void
add_using_namespace (tree user, tree used, bool indirect)
add_using_namespace (tree user, tree used, bool indirect)
{
{
  tree t;
  tree t;
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  /* Using oneself is a no-op.  */
  /* Using oneself is a no-op.  */
  if (user == used)
  if (user == used)
    {
    {
      timevar_pop (TV_NAME_LOOKUP);
      timevar_pop (TV_NAME_LOOKUP);
      return;
      return;
    }
    }
  gcc_assert (TREE_CODE (user) == NAMESPACE_DECL);
  gcc_assert (TREE_CODE (user) == NAMESPACE_DECL);
  gcc_assert (TREE_CODE (used) == NAMESPACE_DECL);
  gcc_assert (TREE_CODE (used) == NAMESPACE_DECL);
  /* Check if we already have this.  */
  /* Check if we already have this.  */
  t = purpose_member (used, DECL_NAMESPACE_USING (user));
  t = purpose_member (used, DECL_NAMESPACE_USING (user));
  if (t != NULL_TREE)
  if (t != NULL_TREE)
    {
    {
      if (!indirect)
      if (!indirect)
        /* Promote to direct usage.  */
        /* Promote to direct usage.  */
        TREE_INDIRECT_USING (t) = 0;
        TREE_INDIRECT_USING (t) = 0;
      timevar_pop (TV_NAME_LOOKUP);
      timevar_pop (TV_NAME_LOOKUP);
      return;
      return;
    }
    }
 
 
  /* Add used to the user's using list.  */
  /* Add used to the user's using list.  */
  DECL_NAMESPACE_USING (user)
  DECL_NAMESPACE_USING (user)
    = tree_cons (used, namespace_ancestor (user, used),
    = tree_cons (used, namespace_ancestor (user, used),
                 DECL_NAMESPACE_USING (user));
                 DECL_NAMESPACE_USING (user));
 
 
  TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
  TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
 
 
  /* Add user to the used's users list.  */
  /* Add user to the used's users list.  */
  DECL_NAMESPACE_USERS (used)
  DECL_NAMESPACE_USERS (used)
    = tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
    = tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
 
 
  /* Recursively add all namespaces used.  */
  /* Recursively add all namespaces used.  */
  for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
  for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
    /* indirect usage */
    /* indirect usage */
    add_using_namespace (user, TREE_PURPOSE (t), 1);
    add_using_namespace (user, TREE_PURPOSE (t), 1);
 
 
  /* Tell everyone using us about the new used namespaces.  */
  /* Tell everyone using us about the new used namespaces.  */
  for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t))
  for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t))
    add_using_namespace (TREE_PURPOSE (t), used, 1);
    add_using_namespace (TREE_PURPOSE (t), used, 1);
  timevar_pop (TV_NAME_LOOKUP);
  timevar_pop (TV_NAME_LOOKUP);
}
}
 
 
/* Process a using-declaration not appearing in class or local scope.  */
/* Process a using-declaration not appearing in class or local scope.  */
 
 
void
void
do_toplevel_using_decl (tree decl, tree scope, tree name)
do_toplevel_using_decl (tree decl, tree scope, tree name)
{
{
  tree oldval, oldtype, newval, newtype;
  tree oldval, oldtype, newval, newtype;
  tree orig_decl = decl;
  tree orig_decl = decl;
  cxx_binding *binding;
  cxx_binding *binding;
 
 
  decl = validate_nonmember_using_decl (decl, scope, name);
  decl = validate_nonmember_using_decl (decl, scope, name);
  if (decl == NULL_TREE)
  if (decl == NULL_TREE)
    return;
    return;
 
 
  binding = binding_for_name (NAMESPACE_LEVEL (current_namespace), name);
  binding = binding_for_name (NAMESPACE_LEVEL (current_namespace), name);
 
 
  oldval = binding->value;
  oldval = binding->value;
  oldtype = binding->type;
  oldtype = binding->type;
 
 
  do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
  do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
 
 
  /* Emit debug info.  */
  /* Emit debug info.  */
  if (!processing_template_decl)
  if (!processing_template_decl)
    cp_emit_debug_info_for_using (orig_decl, current_namespace);
    cp_emit_debug_info_for_using (orig_decl, current_namespace);
 
 
  /* Copy declarations found.  */
  /* Copy declarations found.  */
  if (newval)
  if (newval)
    binding->value = newval;
    binding->value = newval;
  if (newtype)
  if (newtype)
    binding->type = newtype;
    binding->type = newtype;
}
}
 
 
/* Process a using-directive.  */
/* Process a using-directive.  */
 
 
void
void
do_using_directive (tree name_space)
do_using_directive (tree name_space)
{
{
  tree context = NULL_TREE;
  tree context = NULL_TREE;
 
 
  if (name_space == error_mark_node)
  if (name_space == error_mark_node)
    return;
    return;
 
 
  gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
  gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
 
 
  if (building_stmt_tree ())
  if (building_stmt_tree ())
    add_stmt (build_stmt (input_location, USING_STMT, name_space));
    add_stmt (build_stmt (input_location, USING_STMT, name_space));
  name_space = ORIGINAL_NAMESPACE (name_space);
  name_space = ORIGINAL_NAMESPACE (name_space);
 
 
  if (!toplevel_bindings_p ())
  if (!toplevel_bindings_p ())
    {
    {
      push_using_directive (name_space);
      push_using_directive (name_space);
    }
    }
  else
  else
    {
    {
      /* direct usage */
      /* direct usage */
      add_using_namespace (current_namespace, name_space, 0);
      add_using_namespace (current_namespace, name_space, 0);
      if (current_namespace != global_namespace)
      if (current_namespace != global_namespace)
        context = current_namespace;
        context = current_namespace;
 
 
      /* Emit debugging info.  */
      /* Emit debugging info.  */
      if (!processing_template_decl)
      if (!processing_template_decl)
        (*debug_hooks->imported_module_or_decl) (name_space, NULL_TREE,
        (*debug_hooks->imported_module_or_decl) (name_space, NULL_TREE,
                                                 context, false);
                                                 context, false);
    }
    }
}
}
 
 
/* Deal with a using-directive seen by the parser.  Currently we only
/* Deal with a using-directive seen by the parser.  Currently we only
   handle attributes here, since they cannot appear inside a template.  */
   handle attributes here, since they cannot appear inside a template.  */
 
 
void
void
parse_using_directive (tree name_space, tree attribs)
parse_using_directive (tree name_space, tree attribs)
{
{
  tree a;
  tree a;
 
 
  do_using_directive (name_space);
  do_using_directive (name_space);
 
 
  for (a = attribs; a; a = TREE_CHAIN (a))
  for (a = attribs; a; a = TREE_CHAIN (a))
    {
    {
      tree name = TREE_PURPOSE (a);
      tree name = TREE_PURPOSE (a);
      if (is_attribute_p ("strong", name))
      if (is_attribute_p ("strong", name))
        {
        {
          if (!toplevel_bindings_p ())
          if (!toplevel_bindings_p ())
            error ("strong using only meaningful at namespace scope");
            error ("strong using only meaningful at namespace scope");
          else if (name_space != error_mark_node)
          else if (name_space != error_mark_node)
            {
            {
              if (!is_ancestor (current_namespace, name_space))
              if (!is_ancestor (current_namespace, name_space))
                error ("current namespace %qD does not enclose strongly used namespace %qD",
                error ("current namespace %qD does not enclose strongly used namespace %qD",
                       current_namespace, name_space);
                       current_namespace, name_space);
              DECL_NAMESPACE_ASSOCIATIONS (name_space)
              DECL_NAMESPACE_ASSOCIATIONS (name_space)
                = tree_cons (current_namespace, 0,
                = tree_cons (current_namespace, 0,
                             DECL_NAMESPACE_ASSOCIATIONS (name_space));
                             DECL_NAMESPACE_ASSOCIATIONS (name_space));
            }
            }
        }
        }
      else
      else
        warning (OPT_Wattributes, "%qD attribute directive ignored", name);
        warning (OPT_Wattributes, "%qD attribute directive ignored", name);
    }
    }
}
}
 
 
/* Like pushdecl, only it places X in the global scope if appropriate.
/* Like pushdecl, only it places X in the global scope if appropriate.
   Calls cp_finish_decl to register the variable, initializing it with
   Calls cp_finish_decl to register the variable, initializing it with
   *INIT, if INIT is non-NULL.  */
   *INIT, if INIT is non-NULL.  */
 
 
static tree
static tree
pushdecl_top_level_1 (tree x, tree *init, bool is_friend)
pushdecl_top_level_1 (tree x, tree *init, bool is_friend)
{
{
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  push_to_top_level ();
  push_to_top_level ();
  x = pushdecl_namespace_level (x, is_friend);
  x = pushdecl_namespace_level (x, is_friend);
  if (init)
  if (init)
    cp_finish_decl (x, *init, false, NULL_TREE, 0);
    cp_finish_decl (x, *init, false, NULL_TREE, 0);
  pop_from_top_level ();
  pop_from_top_level ();
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
}
}
 
 
/* Like pushdecl, only it places X in the global scope if appropriate.  */
/* Like pushdecl, only it places X in the global scope if appropriate.  */
 
 
tree
tree
pushdecl_top_level (tree x)
pushdecl_top_level (tree x)
{
{
  return pushdecl_top_level_1 (x, NULL, false);
  return pushdecl_top_level_1 (x, NULL, false);
}
}
 
 
/* Like pushdecl_top_level, but adding the IS_FRIEND parameter.  */
/* Like pushdecl_top_level, but adding the IS_FRIEND parameter.  */
 
 
tree
tree
pushdecl_top_level_maybe_friend (tree x, bool is_friend)
pushdecl_top_level_maybe_friend (tree x, bool is_friend)
{
{
  return pushdecl_top_level_1 (x, NULL, is_friend);
  return pushdecl_top_level_1 (x, NULL, is_friend);
}
}
 
 
/* Like pushdecl, only it places X in the global scope if
/* Like pushdecl, only it places X in the global scope if
   appropriate.  Calls cp_finish_decl to register the variable,
   appropriate.  Calls cp_finish_decl to register the variable,
   initializing it with INIT.  */
   initializing it with INIT.  */
 
 
tree
tree
pushdecl_top_level_and_finish (tree x, tree init)
pushdecl_top_level_and_finish (tree x, tree init)
{
{
  return pushdecl_top_level_1 (x, &init, false);
  return pushdecl_top_level_1 (x, &init, false);
}
}
 
 
/* Combines two sets of overloaded functions into an OVERLOAD chain, removing
/* Combines two sets of overloaded functions into an OVERLOAD chain, removing
   duplicates.  The first list becomes the tail of the result.
   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
   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
   doing a sort on the addresses of the functions, if that becomes
   necessary.  */
   necessary.  */
 
 
static tree
static tree
merge_functions (tree s1, tree s2)
merge_functions (tree s1, tree s2)
{
{
  for (; s2; s2 = OVL_NEXT (s2))
  for (; s2; s2 = OVL_NEXT (s2))
    {
    {
      tree fn2 = OVL_CURRENT (s2);
      tree fn2 = OVL_CURRENT (s2);
      tree fns1;
      tree fns1;
 
 
      for (fns1 = s1; fns1; fns1 = OVL_NEXT (fns1))
      for (fns1 = s1; fns1; fns1 = OVL_NEXT (fns1))
        {
        {
          tree fn1 = OVL_CURRENT (fns1);
          tree fn1 = OVL_CURRENT (fns1);
 
 
          /* If the function from S2 is already in S1, there is no
          /* If the function from S2 is already in S1, there is no
             need to add it again.  For `extern "C"' functions, we
             need to add it again.  For `extern "C"' functions, we
             might have two FUNCTION_DECLs for the same function, in
             might have two FUNCTION_DECLs for the same function, in
             different namespaces, but let's leave them in in case
             different namespaces, but let's leave them in in case
             they have different default arguments.  */
             they have different default arguments.  */
          if (fn1 == fn2)
          if (fn1 == fn2)
            break;
            break;
        }
        }
 
 
      /* If we exhausted all of the functions in S1, FN2 is new.  */
      /* If we exhausted all of the functions in S1, FN2 is new.  */
      if (!fns1)
      if (!fns1)
        s1 = build_overload (fn2, s1);
        s1 = build_overload (fn2, s1);
    }
    }
  return s1;
  return s1;
}
}
 
 
/* This should return an error not all definitions define functions.
/* This should return an error not all definitions define functions.
   It is not an error if we find two functions with exactly the
   It is not an error if we find two functions with exactly the
   same signature, only if these are selected in overload resolution.
   same signature, only if these are selected in overload resolution.
   old is the current set of bindings, new_binding the freshly-found binding.
   old is the current set of bindings, new_binding the freshly-found binding.
   XXX Do we want to give *all* candidates in case of ambiguity?
   XXX Do we want to give *all* candidates in case of ambiguity?
   XXX In what way should I treat extern declarations?
   XXX In what way should I treat extern declarations?
   XXX I don't want to repeat the entire duplicate_decls here */
   XXX I don't want to repeat the entire duplicate_decls here */
 
 
static void
static void
ambiguous_decl (struct scope_binding *old, cxx_binding *new_binding, int flags)
ambiguous_decl (struct scope_binding *old, cxx_binding *new_binding, int flags)
{
{
  tree val, type;
  tree val, type;
  gcc_assert (old != NULL);
  gcc_assert (old != NULL);
 
 
  /* Copy the type.  */
  /* Copy the type.  */
  type = new_binding->type;
  type = new_binding->type;
  if (LOOKUP_NAMESPACES_ONLY (flags)
  if (LOOKUP_NAMESPACES_ONLY (flags)
      || (type && hidden_name_p (type) && !(flags & LOOKUP_HIDDEN)))
      || (type && hidden_name_p (type) && !(flags & LOOKUP_HIDDEN)))
    type = NULL_TREE;
    type = NULL_TREE;
 
 
  /* Copy the value.  */
  /* Copy the value.  */
  val = new_binding->value;
  val = new_binding->value;
  if (val)
  if (val)
    {
    {
      if (hidden_name_p (val) && !(flags & LOOKUP_HIDDEN))
      if (hidden_name_p (val) && !(flags & LOOKUP_HIDDEN))
        val = NULL_TREE;
        val = NULL_TREE;
      else
      else
        switch (TREE_CODE (val))
        switch (TREE_CODE (val))
          {
          {
          case TEMPLATE_DECL:
          case TEMPLATE_DECL:
            /* If we expect types or namespaces, and not templates,
            /* If we expect types or namespaces, and not templates,
               or this is not a template class.  */
               or this is not a template class.  */
            if ((LOOKUP_QUALIFIERS_ONLY (flags)
            if ((LOOKUP_QUALIFIERS_ONLY (flags)
                 && !DECL_CLASS_TEMPLATE_P (val)))
                 && !DECL_CLASS_TEMPLATE_P (val)))
              val = NULL_TREE;
              val = NULL_TREE;
            break;
            break;
          case TYPE_DECL:
          case TYPE_DECL:
            if (LOOKUP_NAMESPACES_ONLY (flags)
            if (LOOKUP_NAMESPACES_ONLY (flags)
                || (type && (flags & LOOKUP_PREFER_TYPES)))
                || (type && (flags & LOOKUP_PREFER_TYPES)))
              val = NULL_TREE;
              val = NULL_TREE;
            break;
            break;
          case NAMESPACE_DECL:
          case NAMESPACE_DECL:
            if (LOOKUP_TYPES_ONLY (flags))
            if (LOOKUP_TYPES_ONLY (flags))
              val = NULL_TREE;
              val = NULL_TREE;
            break;
            break;
          case FUNCTION_DECL:
          case FUNCTION_DECL:
            /* Ignore built-in functions that are still anticipated.  */
            /* Ignore built-in functions that are still anticipated.  */
            if (LOOKUP_QUALIFIERS_ONLY (flags))
            if (LOOKUP_QUALIFIERS_ONLY (flags))
              val = NULL_TREE;
              val = NULL_TREE;
            break;
            break;
          default:
          default:
            if (LOOKUP_QUALIFIERS_ONLY (flags))
            if (LOOKUP_QUALIFIERS_ONLY (flags))
              val = NULL_TREE;
              val = NULL_TREE;
          }
          }
    }
    }
 
 
  /* If val is hidden, shift down any class or enumeration name.  */
  /* If val is hidden, shift down any class or enumeration name.  */
  if (!val)
  if (!val)
    {
    {
      val = type;
      val = type;
      type = NULL_TREE;
      type = NULL_TREE;
    }
    }
 
 
  if (!old->value)
  if (!old->value)
    old->value = val;
    old->value = val;
  else if (val && val != old->value)
  else if (val && val != old->value)
    {
    {
      if (is_overloaded_fn (old->value) && is_overloaded_fn (val))
      if (is_overloaded_fn (old->value) && is_overloaded_fn (val))
        old->value = merge_functions (old->value, val);
        old->value = merge_functions (old->value, val);
      else
      else
        {
        {
          old->value = tree_cons (NULL_TREE, old->value,
          old->value = tree_cons (NULL_TREE, old->value,
                                  build_tree_list (NULL_TREE, val));
                                  build_tree_list (NULL_TREE, val));
          TREE_TYPE (old->value) = error_mark_node;
          TREE_TYPE (old->value) = error_mark_node;
        }
        }
    }
    }
 
 
  if (!old->type)
  if (!old->type)
    old->type = type;
    old->type = type;
  else if (type && old->type != type)
  else if (type && old->type != type)
    {
    {
      old->type = tree_cons (NULL_TREE, old->type,
      old->type = tree_cons (NULL_TREE, old->type,
                             build_tree_list (NULL_TREE, type));
                             build_tree_list (NULL_TREE, type));
      TREE_TYPE (old->type) = error_mark_node;
      TREE_TYPE (old->type) = error_mark_node;
    }
    }
}
}
 
 
/* Return the declarations that are members of the namespace NS.  */
/* Return the declarations that are members of the namespace NS.  */
 
 
tree
tree
cp_namespace_decls (tree ns)
cp_namespace_decls (tree ns)
{
{
  return NAMESPACE_LEVEL (ns)->names;
  return NAMESPACE_LEVEL (ns)->names;
}
}
 
 
/* Combine prefer_type and namespaces_only into flags.  */
/* Combine prefer_type and namespaces_only into flags.  */
 
 
static int
static int
lookup_flags (int prefer_type, int namespaces_only)
lookup_flags (int prefer_type, int namespaces_only)
{
{
  if (namespaces_only)
  if (namespaces_only)
    return LOOKUP_PREFER_NAMESPACES;
    return LOOKUP_PREFER_NAMESPACES;
  if (prefer_type > 1)
  if (prefer_type > 1)
    return LOOKUP_PREFER_TYPES;
    return LOOKUP_PREFER_TYPES;
  if (prefer_type > 0)
  if (prefer_type > 0)
    return LOOKUP_PREFER_BOTH;
    return LOOKUP_PREFER_BOTH;
  return 0;
  return 0;
}
}
 
 
/* Given a lookup that returned VAL, use FLAGS to decide if we want to
/* Given a lookup that returned VAL, use FLAGS to decide if we want to
   ignore it or not.  Subroutine of lookup_name_real and
   ignore it or not.  Subroutine of lookup_name_real and
   lookup_type_scope.  */
   lookup_type_scope.  */
 
 
static bool
static bool
qualify_lookup (tree val, int flags)
qualify_lookup (tree val, int flags)
{
{
  if (val == NULL_TREE)
  if (val == NULL_TREE)
    return false;
    return false;
  if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
  if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
    return true;
    return true;
  if ((flags & LOOKUP_PREFER_TYPES)
  if ((flags & LOOKUP_PREFER_TYPES)
      && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
      && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
    return true;
    return true;
  if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
  if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
    return false;
    return false;
  /* In unevaluated context, look past normal capture fields.  */
  /* In unevaluated context, look past normal capture fields.  */
  if (cp_unevaluated_operand && TREE_CODE (val) == FIELD_DECL
  if (cp_unevaluated_operand && TREE_CODE (val) == FIELD_DECL
      && DECL_NORMAL_CAPTURE_P (val))
      && DECL_NORMAL_CAPTURE_P (val))
    return false;
    return false;
  /* None of the lookups that use qualify_lookup want the op() from the
  /* None of the lookups that use qualify_lookup want the op() from the
     lambda; they want the one from the enclosing class.  */
     lambda; they want the one from the enclosing class.  */
  if (TREE_CODE (val) == FUNCTION_DECL && LAMBDA_FUNCTION_P (val))
  if (TREE_CODE (val) == FUNCTION_DECL && LAMBDA_FUNCTION_P (val))
    return false;
    return false;
  return true;
  return true;
}
}
 
 
/* Given a lookup that returned VAL, decide if we want to ignore it or
/* Given a lookup that returned VAL, decide if we want to ignore it or
   not based on DECL_ANTICIPATED.  */
   not based on DECL_ANTICIPATED.  */
 
 
bool
bool
hidden_name_p (tree val)
hidden_name_p (tree val)
{
{
  if (DECL_P (val)
  if (DECL_P (val)
      && DECL_LANG_SPECIFIC (val)
      && DECL_LANG_SPECIFIC (val)
      && DECL_ANTICIPATED (val))
      && DECL_ANTICIPATED (val))
    return true;
    return true;
  return false;
  return false;
}
}
 
 
/* Remove any hidden friend functions from a possibly overloaded set
/* Remove any hidden friend functions from a possibly overloaded set
   of functions.  */
   of functions.  */
 
 
tree
tree
remove_hidden_names (tree fns)
remove_hidden_names (tree fns)
{
{
  if (!fns)
  if (!fns)
    return fns;
    return fns;
 
 
  if (TREE_CODE (fns) == FUNCTION_DECL && hidden_name_p (fns))
  if (TREE_CODE (fns) == FUNCTION_DECL && hidden_name_p (fns))
    fns = NULL_TREE;
    fns = NULL_TREE;
  else if (TREE_CODE (fns) == OVERLOAD)
  else if (TREE_CODE (fns) == OVERLOAD)
    {
    {
      tree o;
      tree o;
 
 
      for (o = fns; o; o = OVL_NEXT (o))
      for (o = fns; o; o = OVL_NEXT (o))
        if (hidden_name_p (OVL_CURRENT (o)))
        if (hidden_name_p (OVL_CURRENT (o)))
          break;
          break;
      if (o)
      if (o)
        {
        {
          tree n = NULL_TREE;
          tree n = NULL_TREE;
 
 
          for (o = fns; o; o = OVL_NEXT (o))
          for (o = fns; o; o = OVL_NEXT (o))
            if (!hidden_name_p (OVL_CURRENT (o)))
            if (!hidden_name_p (OVL_CURRENT (o)))
              n = build_overload (OVL_CURRENT (o), n);
              n = build_overload (OVL_CURRENT (o), n);
          fns = n;
          fns = n;
        }
        }
    }
    }
 
 
  return fns;
  return fns;
}
}
 
 
/* Unscoped lookup of a global: iterate over current namespaces,
/* Unscoped lookup of a global: iterate over current namespaces,
   considering using-directives.  */
   considering using-directives.  */
 
 
static tree
static tree
unqualified_namespace_lookup (tree name, int flags)
unqualified_namespace_lookup (tree name, int flags)
{
{
  tree initial = current_decl_namespace ();
  tree initial = current_decl_namespace ();
  tree scope = initial;
  tree scope = initial;
  tree siter;
  tree siter;
  struct cp_binding_level *level;
  struct cp_binding_level *level;
  tree val = NULL_TREE;
  tree val = NULL_TREE;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
 
 
  for (; !val; scope = CP_DECL_CONTEXT (scope))
  for (; !val; scope = CP_DECL_CONTEXT (scope))
    {
    {
      struct scope_binding binding = EMPTY_SCOPE_BINDING;
      struct scope_binding binding = EMPTY_SCOPE_BINDING;
      cxx_binding *b =
      cxx_binding *b =
         cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
         cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
 
 
      if (b)
      if (b)
        ambiguous_decl (&binding, b, flags);
        ambiguous_decl (&binding, b, flags);
 
 
      /* Add all _DECLs seen through local using-directives.  */
      /* Add all _DECLs seen through local using-directives.  */
      for (level = current_binding_level;
      for (level = current_binding_level;
           level->kind != sk_namespace;
           level->kind != sk_namespace;
           level = level->level_chain)
           level = level->level_chain)
        if (!lookup_using_namespace (name, &binding, level->using_directives,
        if (!lookup_using_namespace (name, &binding, level->using_directives,
                                     scope, flags))
                                     scope, flags))
          /* Give up because of error.  */
          /* Give up because of error.  */
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
 
      /* Add all _DECLs seen through global using-directives.  */
      /* Add all _DECLs seen through global using-directives.  */
      /* XXX local and global using lists should work equally.  */
      /* XXX local and global using lists should work equally.  */
      siter = initial;
      siter = initial;
      while (1)
      while (1)
        {
        {
          if (!lookup_using_namespace (name, &binding,
          if (!lookup_using_namespace (name, &binding,
                                       DECL_NAMESPACE_USING (siter),
                                       DECL_NAMESPACE_USING (siter),
                                       scope, flags))
                                       scope, flags))
            /* Give up because of error.  */
            /* Give up because of error.  */
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
          if (siter == scope) break;
          if (siter == scope) break;
          siter = CP_DECL_CONTEXT (siter);
          siter = CP_DECL_CONTEXT (siter);
        }
        }
 
 
      val = binding.value;
      val = binding.value;
      if (scope == global_namespace)
      if (scope == global_namespace)
        break;
        break;
    }
    }
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
}
}
 
 
/* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL
/* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL
   or a class TYPE).  If IS_TYPE_P is TRUE, then ignore non-type
   or a class TYPE).  If IS_TYPE_P is TRUE, then ignore non-type
   bindings.
   bindings.
 
 
   Returns a DECL (or OVERLOAD, or BASELINK) representing the
   Returns a DECL (or OVERLOAD, or BASELINK) representing the
   declaration found.  If no suitable declaration can be found,
   declaration found.  If no suitable declaration can be found,
   ERROR_MARK_NODE is returned.  If COMPLAIN is true and SCOPE is
   ERROR_MARK_NODE is returned.  If COMPLAIN is true and SCOPE is
   neither a class-type nor a namespace a diagnostic is issued.  */
   neither a class-type nor a namespace a diagnostic is issued.  */
 
 
tree
tree
lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
{
{
  int flags = 0;
  int flags = 0;
  tree t = NULL_TREE;
  tree t = NULL_TREE;
 
 
  if (TREE_CODE (scope) == NAMESPACE_DECL)
  if (TREE_CODE (scope) == NAMESPACE_DECL)
    {
    {
      struct scope_binding binding = EMPTY_SCOPE_BINDING;
      struct scope_binding binding = EMPTY_SCOPE_BINDING;
 
 
      flags |= LOOKUP_COMPLAIN;
      flags |= LOOKUP_COMPLAIN;
      if (is_type_p)
      if (is_type_p)
        flags |= LOOKUP_PREFER_TYPES;
        flags |= LOOKUP_PREFER_TYPES;
      if (qualified_lookup_using_namespace (name, scope, &binding, flags))
      if (qualified_lookup_using_namespace (name, scope, &binding, flags))
        t = binding.value;
        t = binding.value;
    }
    }
  else if (cxx_dialect != cxx98 && TREE_CODE (scope) == ENUMERAL_TYPE)
  else if (cxx_dialect != cxx98 && TREE_CODE (scope) == ENUMERAL_TYPE)
    t = lookup_enumerator (scope, name);
    t = lookup_enumerator (scope, name);
  else if (is_class_type (scope, complain))
  else if (is_class_type (scope, complain))
    t = lookup_member (scope, name, 2, is_type_p);
    t = lookup_member (scope, name, 2, is_type_p);
 
 
  if (!t)
  if (!t)
    return error_mark_node;
    return error_mark_node;
  return t;
  return t;
}
}
 
 
/* Subroutine of unqualified_namespace_lookup:
/* Subroutine of unqualified_namespace_lookup:
   Add the bindings of NAME in used namespaces to VAL.
   Add the bindings of NAME in used namespaces to VAL.
   We are currently looking for names in namespace SCOPE, so we
   We are currently looking for names in namespace SCOPE, so we
   look through USINGS for using-directives of namespaces
   look through USINGS for using-directives of namespaces
   which have SCOPE as a common ancestor with the current scope.
   which have SCOPE as a common ancestor with the current scope.
   Returns false on errors.  */
   Returns false on errors.  */
 
 
static bool
static bool
lookup_using_namespace (tree name, struct scope_binding *val,
lookup_using_namespace (tree name, struct scope_binding *val,
                        tree usings, tree scope, int flags)
                        tree usings, tree scope, int flags)
{
{
  tree iter;
  tree iter;
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  /* Iterate over all used namespaces in current, searching for using
  /* Iterate over all used namespaces in current, searching for using
     directives of scope.  */
     directives of scope.  */
  for (iter = usings; iter; iter = TREE_CHAIN (iter))
  for (iter = usings; iter; iter = TREE_CHAIN (iter))
    if (TREE_VALUE (iter) == scope)
    if (TREE_VALUE (iter) == scope)
      {
      {
        tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
        tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
        cxx_binding *val1 =
        cxx_binding *val1 =
          cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
          cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
        /* Resolve ambiguities.  */
        /* Resolve ambiguities.  */
        if (val1)
        if (val1)
          ambiguous_decl (val, val1, flags);
          ambiguous_decl (val, val1, flags);
      }
      }
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
}
}
 
 
/* Returns true iff VEC contains TARGET.  */
/* Returns true iff VEC contains TARGET.  */
 
 
static bool
static bool
tree_vec_contains (VEC(tree,gc)* vec, tree target)
tree_vec_contains (VEC(tree,gc)* vec, tree target)
{
{
  unsigned int i;
  unsigned int i;
  tree elt;
  tree elt;
  for (i = 0; VEC_iterate(tree,vec,i,elt); ++i)
  for (i = 0; VEC_iterate(tree,vec,i,elt); ++i)
    if (elt == target)
    if (elt == target)
      return true;
      return true;
  return false;
  return false;
}
}
 
 
/* [namespace.qual]
/* [namespace.qual]
   Accepts the NAME to lookup and its qualifying SCOPE.
   Accepts the NAME to lookup and its qualifying SCOPE.
   Returns the name/type pair found into the cxx_binding *RESULT,
   Returns the name/type pair found into the cxx_binding *RESULT,
   or false on error.  */
   or false on error.  */
 
 
static bool
static bool
qualified_lookup_using_namespace (tree name, tree scope,
qualified_lookup_using_namespace (tree name, tree scope,
                                  struct scope_binding *result, int flags)
                                  struct scope_binding *result, int flags)
{
{
  /* Maintain a list of namespaces visited...  */
  /* Maintain a list of namespaces visited...  */
  VEC(tree,gc) *seen = NULL;
  VEC(tree,gc) *seen = NULL;
  VEC(tree,gc) *seen_inline = NULL;
  VEC(tree,gc) *seen_inline = NULL;
  /* ... and a list of namespace yet to see.  */
  /* ... and a list of namespace yet to see.  */
  VEC(tree,gc) *todo = NULL;
  VEC(tree,gc) *todo = NULL;
  VEC(tree,gc) *todo_maybe = NULL;
  VEC(tree,gc) *todo_maybe = NULL;
  VEC(tree,gc) *todo_inline = NULL;
  VEC(tree,gc) *todo_inline = NULL;
  tree usings;
  tree usings;
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  /* Look through namespace aliases.  */
  /* Look through namespace aliases.  */
  scope = ORIGINAL_NAMESPACE (scope);
  scope = ORIGINAL_NAMESPACE (scope);
 
 
  /* Algorithm: Starting with SCOPE, walk through the the set of used
  /* Algorithm: Starting with SCOPE, walk through the the set of used
     namespaces.  For each used namespace, look through its inline
     namespaces.  For each used namespace, look through its inline
     namespace set for any bindings and usings.  If no bindings are found,
     namespace set for any bindings and usings.  If no bindings are found,
     add any usings seen to the set of used namespaces.  */
     add any usings seen to the set of used namespaces.  */
  VEC_safe_push (tree, gc, todo, scope);
  VEC_safe_push (tree, gc, todo, scope);
 
 
  while (VEC_length (tree, todo))
  while (VEC_length (tree, todo))
    {
    {
      bool found_here;
      bool found_here;
      scope = VEC_pop (tree, todo);
      scope = VEC_pop (tree, todo);
      if (tree_vec_contains (seen, scope))
      if (tree_vec_contains (seen, scope))
        continue;
        continue;
      VEC_safe_push (tree, gc, seen, scope);
      VEC_safe_push (tree, gc, seen, scope);
      VEC_safe_push (tree, gc, todo_inline, scope);
      VEC_safe_push (tree, gc, todo_inline, scope);
 
 
      found_here = false;
      found_here = false;
      while (VEC_length (tree, todo_inline))
      while (VEC_length (tree, todo_inline))
        {
        {
          cxx_binding *binding;
          cxx_binding *binding;
 
 
          scope = VEC_pop (tree, todo_inline);
          scope = VEC_pop (tree, todo_inline);
          if (tree_vec_contains (seen_inline, scope))
          if (tree_vec_contains (seen_inline, scope))
            continue;
            continue;
          VEC_safe_push (tree, gc, seen_inline, scope);
          VEC_safe_push (tree, gc, seen_inline, scope);
 
 
          binding =
          binding =
            cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
            cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
          if (binding)
          if (binding)
            {
            {
              found_here = true;
              found_here = true;
              ambiguous_decl (result, binding, flags);
              ambiguous_decl (result, binding, flags);
            }
            }
 
 
          for (usings = DECL_NAMESPACE_USING (scope); usings;
          for (usings = DECL_NAMESPACE_USING (scope); usings;
               usings = TREE_CHAIN (usings))
               usings = TREE_CHAIN (usings))
            if (!TREE_INDIRECT_USING (usings))
            if (!TREE_INDIRECT_USING (usings))
              {
              {
                if (is_associated_namespace (scope, TREE_PURPOSE (usings)))
                if (is_associated_namespace (scope, TREE_PURPOSE (usings)))
                  VEC_safe_push (tree, gc, todo_inline, TREE_PURPOSE (usings));
                  VEC_safe_push (tree, gc, todo_inline, TREE_PURPOSE (usings));
                else
                else
                  VEC_safe_push (tree, gc, todo_maybe, TREE_PURPOSE (usings));
                  VEC_safe_push (tree, gc, todo_maybe, TREE_PURPOSE (usings));
              }
              }
        }
        }
 
 
      if (found_here)
      if (found_here)
        VEC_truncate (tree, todo_maybe, 0);
        VEC_truncate (tree, todo_maybe, 0);
      else
      else
        while (VEC_length (tree, todo_maybe))
        while (VEC_length (tree, todo_maybe))
          VEC_safe_push (tree, gc, todo, VEC_pop (tree, todo_maybe));
          VEC_safe_push (tree, gc, todo, VEC_pop (tree, todo_maybe));
    }
    }
  VEC_free (tree,gc,todo);
  VEC_free (tree,gc,todo);
  VEC_free (tree,gc,todo_maybe);
  VEC_free (tree,gc,todo_maybe);
  VEC_free (tree,gc,todo_inline);
  VEC_free (tree,gc,todo_inline);
  VEC_free (tree,gc,seen);
  VEC_free (tree,gc,seen);
  VEC_free (tree,gc,seen_inline);
  VEC_free (tree,gc,seen_inline);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
}
}
 
 
/* Subroutine of outer_binding.
/* Subroutine of outer_binding.
   Returns TRUE if BINDING is a binding to a template parameter of SCOPE,
   Returns TRUE if BINDING is a binding to a template parameter of SCOPE,
   FALSE otherwise.  */
   FALSE otherwise.  */
 
 
static bool
static bool
binding_to_template_parms_of_scope_p (cxx_binding *binding,
binding_to_template_parms_of_scope_p (cxx_binding *binding,
                                      cxx_scope *scope)
                                      cxx_scope *scope)
{
{
  tree binding_value;
  tree binding_value;
 
 
  if (!binding || !scope)
  if (!binding || !scope)
    return false;
    return false;
 
 
  binding_value = binding->value ?  binding->value : binding->type;
  binding_value = binding->value ?  binding->value : binding->type;
 
 
  return (scope
  return (scope
          && scope->this_entity
          && scope->this_entity
          && get_template_info (scope->this_entity)
          && get_template_info (scope->this_entity)
          && parameter_of_template_p (binding_value,
          && parameter_of_template_p (binding_value,
                                      TI_TEMPLATE (get_template_info \
                                      TI_TEMPLATE (get_template_info \
                                                    (scope->this_entity))));
                                                    (scope->this_entity))));
}
}
 
 
/* Return the innermost non-namespace binding for NAME from a scope
/* Return the innermost non-namespace binding for NAME from a scope
   containing BINDING, or, if BINDING is NULL, the current scope.
   containing BINDING, or, if BINDING is NULL, the current scope.
   Please note that for a given template, the template parameters are
   Please note that for a given template, the template parameters are
   considered to be in the scope containing the current scope.
   considered to be in the scope containing the current scope.
   If CLASS_P is false, then class bindings are ignored.  */
   If CLASS_P is false, then class bindings are ignored.  */
 
 
cxx_binding *
cxx_binding *
outer_binding (tree name,
outer_binding (tree name,
               cxx_binding *binding,
               cxx_binding *binding,
               bool class_p)
               bool class_p)
{
{
  cxx_binding *outer;
  cxx_binding *outer;
  cxx_scope *scope;
  cxx_scope *scope;
  cxx_scope *outer_scope;
  cxx_scope *outer_scope;
 
 
  if (binding)
  if (binding)
    {
    {
      scope = binding->scope->level_chain;
      scope = binding->scope->level_chain;
      outer = binding->previous;
      outer = binding->previous;
    }
    }
  else
  else
    {
    {
      scope = current_binding_level;
      scope = current_binding_level;
      outer = IDENTIFIER_BINDING (name);
      outer = IDENTIFIER_BINDING (name);
    }
    }
  outer_scope = outer ? outer->scope : NULL;
  outer_scope = outer ? outer->scope : NULL;
 
 
  /* Because we create class bindings lazily, we might be missing a
  /* Because we create class bindings lazily, we might be missing a
     class binding for NAME.  If there are any class binding levels
     class binding for NAME.  If there are any class binding levels
     between the LAST_BINDING_LEVEL and the scope in which OUTER was
     between the LAST_BINDING_LEVEL and the scope in which OUTER was
     declared, we must lookup NAME in those class scopes.  */
     declared, we must lookup NAME in those class scopes.  */
  if (class_p)
  if (class_p)
    while (scope && scope != outer_scope && scope->kind != sk_namespace)
    while (scope && scope != outer_scope && scope->kind != sk_namespace)
      {
      {
        if (scope->kind == sk_class)
        if (scope->kind == sk_class)
          {
          {
            cxx_binding *class_binding;
            cxx_binding *class_binding;
 
 
            class_binding = get_class_binding (name, scope);
            class_binding = get_class_binding (name, scope);
            if (class_binding)
            if (class_binding)
              {
              {
                /* Thread this new class-scope binding onto the
                /* Thread this new class-scope binding onto the
                   IDENTIFIER_BINDING list so that future lookups
                   IDENTIFIER_BINDING list so that future lookups
                   find it quickly.  */
                   find it quickly.  */
                class_binding->previous = outer;
                class_binding->previous = outer;
                if (binding)
                if (binding)
                  binding->previous = class_binding;
                  binding->previous = class_binding;
                else
                else
                  IDENTIFIER_BINDING (name) = class_binding;
                  IDENTIFIER_BINDING (name) = class_binding;
                return class_binding;
                return class_binding;
              }
              }
          }
          }
        /* If we are in a member template, the template parms of the member
        /* If we are in a member template, the template parms of the member
           template are considered to be inside the scope of the containing
           template are considered to be inside the scope of the containing
           class, but within G++ the class bindings are all pushed between the
           class, but within G++ the class bindings are all pushed between the
           template parms and the function body.  So if the outer binding is
           template parms and the function body.  So if the outer binding is
           a template parm for the current scope, return it now rather than
           a template parm for the current scope, return it now rather than
           look for a class binding.  */
           look for a class binding.  */
        if (outer_scope && outer_scope->kind == sk_template_parms
        if (outer_scope && outer_scope->kind == sk_template_parms
            && binding_to_template_parms_of_scope_p (outer, scope))
            && binding_to_template_parms_of_scope_p (outer, scope))
          return outer;
          return outer;
 
 
        scope = scope->level_chain;
        scope = scope->level_chain;
      }
      }
 
 
  return outer;
  return outer;
}
}
 
 
/* Return the innermost block-scope or class-scope value binding for
/* Return the innermost block-scope or class-scope value binding for
   NAME, or NULL_TREE if there is no such binding.  */
   NAME, or NULL_TREE if there is no such binding.  */
 
 
tree
tree
innermost_non_namespace_value (tree name)
innermost_non_namespace_value (tree name)
{
{
  cxx_binding *binding;
  cxx_binding *binding;
  binding = outer_binding (name, /*binding=*/NULL, /*class_p=*/true);
  binding = outer_binding (name, /*binding=*/NULL, /*class_p=*/true);
  return binding ? binding->value : NULL_TREE;
  return binding ? binding->value : NULL_TREE;
}
}
 
 
/* Look up NAME in the current binding level and its superiors in the
/* Look up NAME in the current binding level and its superiors in the
   namespace of variables, functions and typedefs.  Return a ..._DECL
   namespace of variables, functions and typedefs.  Return a ..._DECL
   node of some kind representing its definition if there is only one
   node of some kind representing its definition if there is only one
   such declaration, or return a TREE_LIST with all the overloaded
   such declaration, or return a TREE_LIST with all the overloaded
   definitions if there are many, or return 0 if it is undefined.
   definitions if there are many, or return 0 if it is undefined.
   Hidden name, either friend declaration or built-in function, are
   Hidden name, either friend declaration or built-in function, are
   not ignored.
   not ignored.
 
 
   If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
   If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
   If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
   If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
   Otherwise we prefer non-TYPE_DECLs.
   Otherwise we prefer non-TYPE_DECLs.
 
 
   If NONCLASS is nonzero, bindings in class scopes are ignored.  If
   If NONCLASS is nonzero, bindings in class scopes are ignored.  If
   BLOCK_P is false, bindings in block scopes are ignored.  */
   BLOCK_P is false, bindings in block scopes are ignored.  */
 
 
tree
tree
lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
                  int namespaces_only, int flags)
                  int namespaces_only, int flags)
{
{
  cxx_binding *iter;
  cxx_binding *iter;
  tree val = NULL_TREE;
  tree val = NULL_TREE;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  /* Conversion operators are handled specially because ordinary
  /* Conversion operators are handled specially because ordinary
     unqualified name lookup will not find template conversion
     unqualified name lookup will not find template conversion
     operators.  */
     operators.  */
  if (IDENTIFIER_TYPENAME_P (name))
  if (IDENTIFIER_TYPENAME_P (name))
    {
    {
      struct cp_binding_level *level;
      struct cp_binding_level *level;
 
 
      for (level = current_binding_level;
      for (level = current_binding_level;
           level && level->kind != sk_namespace;
           level && level->kind != sk_namespace;
           level = level->level_chain)
           level = level->level_chain)
        {
        {
          tree class_type;
          tree class_type;
          tree operators;
          tree operators;
 
 
          /* A conversion operator can only be declared in a class
          /* A conversion operator can only be declared in a class
             scope.  */
             scope.  */
          if (level->kind != sk_class)
          if (level->kind != sk_class)
            continue;
            continue;
 
 
          /* Lookup the conversion operator in the class.  */
          /* Lookup the conversion operator in the class.  */
          class_type = level->this_entity;
          class_type = level->this_entity;
          operators = lookup_fnfields (class_type, name, /*protect=*/0);
          operators = lookup_fnfields (class_type, name, /*protect=*/0);
          if (operators)
          if (operators)
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators);
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators);
        }
        }
 
 
      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
    }
    }
 
 
  flags |= lookup_flags (prefer_type, namespaces_only);
  flags |= lookup_flags (prefer_type, namespaces_only);
 
 
  /* First, look in non-namespace scopes.  */
  /* First, look in non-namespace scopes.  */
 
 
  if (current_class_type == NULL_TREE)
  if (current_class_type == NULL_TREE)
    nonclass = 1;
    nonclass = 1;
 
 
  if (block_p || !nonclass)
  if (block_p || !nonclass)
    for (iter = outer_binding (name, NULL, !nonclass);
    for (iter = outer_binding (name, NULL, !nonclass);
         iter;
         iter;
         iter = outer_binding (name, iter, !nonclass))
         iter = outer_binding (name, iter, !nonclass))
      {
      {
        tree binding;
        tree binding;
 
 
        /* Skip entities we don't want.  */
        /* Skip entities we don't want.  */
        if (LOCAL_BINDING_P (iter) ? !block_p : nonclass)
        if (LOCAL_BINDING_P (iter) ? !block_p : nonclass)
          continue;
          continue;
 
 
        /* If this is the kind of thing we're looking for, we're done.  */
        /* If this is the kind of thing we're looking for, we're done.  */
        if (qualify_lookup (iter->value, flags))
        if (qualify_lookup (iter->value, flags))
          binding = iter->value;
          binding = iter->value;
        else if ((flags & LOOKUP_PREFER_TYPES)
        else if ((flags & LOOKUP_PREFER_TYPES)
                 && qualify_lookup (iter->type, flags))
                 && qualify_lookup (iter->type, flags))
          binding = iter->type;
          binding = iter->type;
        else
        else
          binding = NULL_TREE;
          binding = NULL_TREE;
 
 
        if (binding)
        if (binding)
          {
          {
            if (hidden_name_p (binding))
            if (hidden_name_p (binding))
              {
              {
                /* A non namespace-scope binding can only be hidden in the
                /* A non namespace-scope binding can only be hidden in the
                   presence of a local class, due to friend declarations.
                   presence of a local class, due to friend declarations.
 
 
                   In particular, consider:
                   In particular, consider:
 
 
                   struct C;
                   struct C;
                   void f() {
                   void f() {
                     struct A {
                     struct A {
                       friend struct B;
                       friend struct B;
                       friend struct C;
                       friend struct C;
                       void g() {
                       void g() {
                         B* b; // error: B is hidden
                         B* b; // error: B is hidden
                         C* c; // OK, finds ::C
                         C* c; // OK, finds ::C
                       }
                       }
                     };
                     };
                     B *b;  // error: B is hidden
                     B *b;  // error: B is hidden
                     C *c;  // OK, finds ::C
                     C *c;  // OK, finds ::C
                     struct B {};
                     struct B {};
                     B *bb; // OK
                     B *bb; // OK
                   }
                   }
 
 
                   The standard says that "B" is a local class in "f"
                   The standard says that "B" is a local class in "f"
                   (but not nested within "A") -- but that name lookup
                   (but not nested within "A") -- but that name lookup
                   for "B" does not find this declaration until it is
                   for "B" does not find this declaration until it is
                   declared directly with "f".
                   declared directly with "f".
 
 
                   In particular:
                   In particular:
 
 
                   [class.friend]
                   [class.friend]
 
 
                   If a friend declaration appears in a local class and
                   If a friend declaration appears in a local class and
                   the name specified is an unqualified name, a prior
                   the name specified is an unqualified name, a prior
                   declaration is looked up without considering scopes
                   declaration is looked up without considering scopes
                   that are outside the innermost enclosing non-class
                   that are outside the innermost enclosing non-class
                   scope. For a friend function declaration, if there is
                   scope. For a friend function declaration, if there is
                   no prior declaration, the program is ill-formed. For a
                   no prior declaration, the program is ill-formed. For a
                   friend class declaration, if there is no prior
                   friend class declaration, if there is no prior
                   declaration, the class that is specified belongs to the
                   declaration, the class that is specified belongs to the
                   innermost enclosing non-class scope, but if it is
                   innermost enclosing non-class scope, but if it is
                   subsequently referenced, its name is not found by name
                   subsequently referenced, its name is not found by name
                   lookup until a matching declaration is provided in the
                   lookup until a matching declaration is provided in the
                   innermost enclosing nonclass scope.
                   innermost enclosing nonclass scope.
 
 
                   So just keep looking for a non-hidden binding.
                   So just keep looking for a non-hidden binding.
                */
                */
                gcc_assert (TREE_CODE (binding) == TYPE_DECL);
                gcc_assert (TREE_CODE (binding) == TYPE_DECL);
                continue;
                continue;
              }
              }
            val = binding;
            val = binding;
            break;
            break;
          }
          }
      }
      }
 
 
  /* Now lookup in namespace scopes.  */
  /* Now lookup in namespace scopes.  */
  if (!val)
  if (!val)
    val = unqualified_namespace_lookup (name, flags);
    val = unqualified_namespace_lookup (name, flags);
 
 
  /* If we have a single function from a using decl, pull it out.  */
  /* If we have a single function from a using decl, pull it out.  */
  if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val))
  if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val))
    val = OVL_FUNCTION (val);
    val = OVL_FUNCTION (val);
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
}
}
 
 
tree
tree
lookup_name_nonclass (tree name)
lookup_name_nonclass (tree name)
{
{
  return lookup_name_real (name, 0, 1, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
  return lookup_name_real (name, 0, 1, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
}
}
 
 
tree
tree
lookup_function_nonclass (tree name, VEC(tree,gc) *args, bool block_p)
lookup_function_nonclass (tree name, VEC(tree,gc) *args, bool block_p)
{
{
  return
  return
    lookup_arg_dependent (name,
    lookup_arg_dependent (name,
                          lookup_name_real (name, 0, 1, block_p, 0,
                          lookup_name_real (name, 0, 1, block_p, 0,
                                            LOOKUP_COMPLAIN),
                                            LOOKUP_COMPLAIN),
                          args);
                          args);
}
}
 
 
tree
tree
lookup_name (tree name)
lookup_name (tree name)
{
{
  return lookup_name_real (name, 0, 0, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
  return lookup_name_real (name, 0, 0, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
}
}
 
 
tree
tree
lookup_name_prefer_type (tree name, int prefer_type)
lookup_name_prefer_type (tree name, int prefer_type)
{
{
  return lookup_name_real (name, prefer_type, 0, /*block_p=*/true,
  return lookup_name_real (name, prefer_type, 0, /*block_p=*/true,
                           0, LOOKUP_COMPLAIN);
                           0, LOOKUP_COMPLAIN);
}
}
 
 
/* Look up NAME for type used in elaborated name specifier in
/* Look up NAME for type used in elaborated name specifier in
   the scopes given by SCOPE.  SCOPE can be either TS_CURRENT or
   the scopes given by SCOPE.  SCOPE can be either TS_CURRENT or
   TS_WITHIN_ENCLOSING_NON_CLASS.  Although not implied by the
   TS_WITHIN_ENCLOSING_NON_CLASS.  Although not implied by the
   name, more scopes are checked if cleanup or template parameter
   name, more scopes are checked if cleanup or template parameter
   scope is encountered.
   scope is encountered.
 
 
   Unlike lookup_name_real, we make sure that NAME is actually
   Unlike lookup_name_real, we make sure that NAME is actually
   declared in the desired scope, not from inheritance, nor using
   declared in the desired scope, not from inheritance, nor using
   directive.  For using declaration, there is DR138 still waiting
   directive.  For using declaration, there is DR138 still waiting
   to be resolved.  Hidden name coming from an earlier friend
   to be resolved.  Hidden name coming from an earlier friend
   declaration is also returned.
   declaration is also returned.
 
 
   A TYPE_DECL best matching the NAME is returned.  Catching error
   A TYPE_DECL best matching the NAME is returned.  Catching error
   and issuing diagnostics are caller's responsibility.  */
   and issuing diagnostics are caller's responsibility.  */
 
 
tree
tree
lookup_type_scope (tree name, tag_scope scope)
lookup_type_scope (tree name, tag_scope scope)
{
{
  cxx_binding *iter = NULL;
  cxx_binding *iter = NULL;
  tree val = NULL_TREE;
  tree val = NULL_TREE;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
 
 
  /* Look in non-namespace scope first.  */
  /* Look in non-namespace scope first.  */
  if (current_binding_level->kind != sk_namespace)
  if (current_binding_level->kind != sk_namespace)
    iter = outer_binding (name, NULL, /*class_p=*/ true);
    iter = outer_binding (name, NULL, /*class_p=*/ true);
  for (; iter; iter = outer_binding (name, iter, /*class_p=*/ true))
  for (; iter; iter = outer_binding (name, iter, /*class_p=*/ true))
    {
    {
      /* Check if this is the kind of thing we're looking for.
      /* Check if this is the kind of thing we're looking for.
         If SCOPE is TS_CURRENT, also make sure it doesn't come from
         If SCOPE is TS_CURRENT, also make sure it doesn't come from
         base class.  For ITER->VALUE, we can simply use
         base class.  For ITER->VALUE, we can simply use
         INHERITED_VALUE_BINDING_P.  For ITER->TYPE, we have to use
         INHERITED_VALUE_BINDING_P.  For ITER->TYPE, we have to use
         our own check.
         our own check.
 
 
         We check ITER->TYPE before ITER->VALUE in order to handle
         We check ITER->TYPE before ITER->VALUE in order to handle
           typedef struct C {} C;
           typedef struct C {} C;
         correctly.  */
         correctly.  */
 
 
      if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES)
      if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES)
          && (scope != ts_current
          && (scope != ts_current
              || LOCAL_BINDING_P (iter)
              || LOCAL_BINDING_P (iter)
              || DECL_CONTEXT (iter->type) == iter->scope->this_entity))
              || DECL_CONTEXT (iter->type) == iter->scope->this_entity))
        val = iter->type;
        val = iter->type;
      else if ((scope != ts_current
      else if ((scope != ts_current
                || !INHERITED_VALUE_BINDING_P (iter))
                || !INHERITED_VALUE_BINDING_P (iter))
               && qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
               && qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
        val = iter->value;
        val = iter->value;
 
 
      if (val)
      if (val)
        break;
        break;
    }
    }
 
 
  /* Look in namespace scope.  */
  /* Look in namespace scope.  */
  if (!val)
  if (!val)
    {
    {
      iter = cxx_scope_find_binding_for_name
      iter = cxx_scope_find_binding_for_name
               (NAMESPACE_LEVEL (current_decl_namespace ()), name);
               (NAMESPACE_LEVEL (current_decl_namespace ()), name);
 
 
      if (iter)
      if (iter)
        {
        {
          /* If this is the kind of thing we're looking for, we're done.  */
          /* If this is the kind of thing we're looking for, we're done.  */
          if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES))
          if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES))
            val = iter->type;
            val = iter->type;
          else if (qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
          else if (qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
            val = iter->value;
            val = iter->value;
        }
        }
 
 
    }
    }
 
 
  /* Type found, check if it is in the allowed scopes, ignoring cleanup
  /* Type found, check if it is in the allowed scopes, ignoring cleanup
     and template parameter scopes.  */
     and template parameter scopes.  */
  if (val)
  if (val)
    {
    {
      struct cp_binding_level *b = current_binding_level;
      struct cp_binding_level *b = current_binding_level;
      while (b)
      while (b)
        {
        {
          if (iter->scope == b)
          if (iter->scope == b)
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
 
 
          if (b->kind == sk_cleanup || b->kind == sk_template_parms
          if (b->kind == sk_cleanup || b->kind == sk_template_parms
              || b->kind == sk_function_parms)
              || b->kind == sk_function_parms)
            b = b->level_chain;
            b = b->level_chain;
          else if (b->kind == sk_class
          else if (b->kind == sk_class
                   && scope == ts_within_enclosing_non_class)
                   && scope == ts_within_enclosing_non_class)
            b = b->level_chain;
            b = b->level_chain;
          else
          else
            break;
            break;
        }
        }
    }
    }
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
}
 
 
/* Similar to `lookup_name' but look only in the innermost non-class
/* Similar to `lookup_name' but look only in the innermost non-class
   binding level.  */
   binding level.  */
 
 
tree
tree
lookup_name_innermost_nonclass_level (tree name)
lookup_name_innermost_nonclass_level (tree name)
{
{
  struct cp_binding_level *b;
  struct cp_binding_level *b;
  tree t = NULL_TREE;
  tree t = NULL_TREE;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  b = innermost_nonclass_level ();
  b = innermost_nonclass_level ();
 
 
  if (b->kind == sk_namespace)
  if (b->kind == sk_namespace)
    {
    {
      t = IDENTIFIER_NAMESPACE_VALUE (name);
      t = IDENTIFIER_NAMESPACE_VALUE (name);
 
 
      /* extern "C" function() */
      /* extern "C" function() */
      if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
      if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
        t = TREE_VALUE (t);
        t = TREE_VALUE (t);
    }
    }
  else if (IDENTIFIER_BINDING (name)
  else if (IDENTIFIER_BINDING (name)
           && LOCAL_BINDING_P (IDENTIFIER_BINDING (name)))
           && LOCAL_BINDING_P (IDENTIFIER_BINDING (name)))
    {
    {
      cxx_binding *binding;
      cxx_binding *binding;
      binding = IDENTIFIER_BINDING (name);
      binding = IDENTIFIER_BINDING (name);
      while (1)
      while (1)
        {
        {
          if (binding->scope == b
          if (binding->scope == b
              && !(TREE_CODE (binding->value) == VAR_DECL
              && !(TREE_CODE (binding->value) == VAR_DECL
                   && DECL_DEAD_FOR_LOCAL (binding->value)))
                   && DECL_DEAD_FOR_LOCAL (binding->value)))
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding->value);
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding->value);
 
 
          if (b->kind == sk_cleanup)
          if (b->kind == sk_cleanup)
            b = b->level_chain;
            b = b->level_chain;
          else
          else
            break;
            break;
        }
        }
    }
    }
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
}
 
 
/* Returns true iff DECL is a block-scope extern declaration of a function
/* Returns true iff DECL is a block-scope extern declaration of a function
   or variable.  */
   or variable.  */
 
 
bool
bool
is_local_extern (tree decl)
is_local_extern (tree decl)
{
{
  cxx_binding *binding;
  cxx_binding *binding;
 
 
  /* For functions, this is easy.  */
  /* For functions, this is easy.  */
  if (TREE_CODE (decl) == FUNCTION_DECL)
  if (TREE_CODE (decl) == FUNCTION_DECL)
    return DECL_LOCAL_FUNCTION_P (decl);
    return DECL_LOCAL_FUNCTION_P (decl);
 
 
  if (TREE_CODE (decl) != VAR_DECL)
  if (TREE_CODE (decl) != VAR_DECL)
    return false;
    return false;
  if (!current_function_decl)
  if (!current_function_decl)
    return false;
    return false;
 
 
  /* For variables, this is not easy.  We need to look at the binding stack
  /* For variables, this is not easy.  We need to look at the binding stack
     for the identifier to see whether the decl we have is a local.  */
     for the identifier to see whether the decl we have is a local.  */
  for (binding = IDENTIFIER_BINDING (DECL_NAME (decl));
  for (binding = IDENTIFIER_BINDING (DECL_NAME (decl));
       binding && binding->scope->kind != sk_namespace;
       binding && binding->scope->kind != sk_namespace;
       binding = binding->previous)
       binding = binding->previous)
    if (binding->value == decl)
    if (binding->value == decl)
      return LOCAL_BINDING_P (binding);
      return LOCAL_BINDING_P (binding);
 
 
  return false;
  return false;
}
}
 
 
/* Like lookup_name_innermost_nonclass_level, but for types.  */
/* Like lookup_name_innermost_nonclass_level, but for types.  */
 
 
static tree
static tree
lookup_type_current_level (tree name)
lookup_type_current_level (tree name)
{
{
  tree t = NULL_TREE;
  tree t = NULL_TREE;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  gcc_assert (current_binding_level->kind != sk_namespace);
  gcc_assert (current_binding_level->kind != sk_namespace);
 
 
  if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
  if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
      && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
      && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
    {
    {
      struct cp_binding_level *b = current_binding_level;
      struct cp_binding_level *b = current_binding_level;
      while (1)
      while (1)
        {
        {
          if (purpose_member (name, b->type_shadowed))
          if (purpose_member (name, b->type_shadowed))
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
                                    REAL_IDENTIFIER_TYPE_VALUE (name));
                                    REAL_IDENTIFIER_TYPE_VALUE (name));
          if (b->kind == sk_cleanup)
          if (b->kind == sk_cleanup)
            b = b->level_chain;
            b = b->level_chain;
          else
          else
            break;
            break;
        }
        }
    }
    }
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
}
 
 
/* [basic.lookup.koenig] */
/* [basic.lookup.koenig] */
/* A nonzero return value in the functions below indicates an error.  */
/* A nonzero return value in the functions below indicates an error.  */
 
 
struct arg_lookup
struct arg_lookup
{
{
  tree name;
  tree name;
  VEC(tree,gc) *args;
  VEC(tree,gc) *args;
  tree namespaces;
  tree namespaces;
  tree classes;
  tree classes;
  tree functions;
  tree functions;
};
};
 
 
static bool arg_assoc (struct arg_lookup*, tree);
static bool arg_assoc (struct arg_lookup*, tree);
static bool arg_assoc_args (struct arg_lookup*, tree);
static bool arg_assoc_args (struct arg_lookup*, tree);
static bool arg_assoc_args_vec (struct arg_lookup*, VEC(tree,gc) *);
static bool arg_assoc_args_vec (struct arg_lookup*, VEC(tree,gc) *);
static bool arg_assoc_type (struct arg_lookup*, tree);
static bool arg_assoc_type (struct arg_lookup*, tree);
static bool add_function (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_namespace (struct arg_lookup *, tree);
static bool arg_assoc_class_only (struct arg_lookup *, tree);
static bool arg_assoc_class_only (struct arg_lookup *, tree);
static bool arg_assoc_bases (struct arg_lookup *, tree);
static bool arg_assoc_bases (struct arg_lookup *, tree);
static bool arg_assoc_class (struct arg_lookup *, tree);
static bool arg_assoc_class (struct arg_lookup *, tree);
static bool arg_assoc_template_arg (struct arg_lookup*, tree);
static bool arg_assoc_template_arg (struct arg_lookup*, tree);
 
 
/* Add a function to the lookup structure.
/* Add a function to the lookup structure.
   Returns true on error.  */
   Returns true on error.  */
 
 
static bool
static bool
add_function (struct arg_lookup *k, tree fn)
add_function (struct arg_lookup *k, tree fn)
{
{
  /* We used to check here to see if the function was already in the list,
  /* 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.
     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
     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
     assume that the number of duplicates will be small compared to the
     total number of functions being compared, which should usually be the
     total number of functions being compared, which should usually be the
     case.  */
     case.  */
 
 
  if (!is_overloaded_fn (fn))
  if (!is_overloaded_fn (fn))
    /* All names except those of (possibly overloaded) functions and
    /* All names except those of (possibly overloaded) functions and
       function templates are ignored.  */;
       function templates are ignored.  */;
  else if (!k->functions)
  else if (!k->functions)
    k->functions = fn;
    k->functions = fn;
  else if (fn == k->functions)
  else if (fn == k->functions)
    ;
    ;
  else
  else
    k->functions = build_overload (fn, k->functions);
    k->functions = build_overload (fn, k->functions);
 
 
  return false;
  return false;
}
}
 
 
/* Returns true iff CURRENT has declared itself to be an associated
/* Returns true iff CURRENT has declared itself to be an associated
   namespace of SCOPE via a strong using-directive (or transitive chain
   namespace of SCOPE via a strong using-directive (or transitive chain
   thereof).  Both are namespaces.  */
   thereof).  Both are namespaces.  */
 
 
bool
bool
is_associated_namespace (tree current, tree scope)
is_associated_namespace (tree current, tree scope)
{
{
  tree seen = NULL_TREE;
  tree seen = NULL_TREE;
  tree todo = NULL_TREE;
  tree todo = NULL_TREE;
  tree t;
  tree t;
  while (1)
  while (1)
    {
    {
      if (scope == current)
      if (scope == current)
        return true;
        return true;
      seen = tree_cons (scope, NULL_TREE, seen);
      seen = tree_cons (scope, NULL_TREE, seen);
      for (t = DECL_NAMESPACE_ASSOCIATIONS (scope); t; t = TREE_CHAIN (t))
      for (t = DECL_NAMESPACE_ASSOCIATIONS (scope); t; t = TREE_CHAIN (t))
        if (!purpose_member (TREE_PURPOSE (t), seen))
        if (!purpose_member (TREE_PURPOSE (t), seen))
          todo = tree_cons (TREE_PURPOSE (t), NULL_TREE, todo);
          todo = tree_cons (TREE_PURPOSE (t), NULL_TREE, todo);
      if (todo)
      if (todo)
        {
        {
          scope = TREE_PURPOSE (todo);
          scope = TREE_PURPOSE (todo);
          todo = TREE_CHAIN (todo);
          todo = TREE_CHAIN (todo);
        }
        }
      else
      else
        return false;
        return false;
    }
    }
}
}
 
 
/* Add functions of a namespace to the lookup structure.
/* Add functions of a namespace to the lookup structure.
   Returns true on error.  */
   Returns true on error.  */
 
 
static bool
static bool
arg_assoc_namespace (struct arg_lookup *k, tree scope)
arg_assoc_namespace (struct arg_lookup *k, tree scope)
{
{
  tree value;
  tree value;
 
 
  if (purpose_member (scope, k->namespaces))
  if (purpose_member (scope, k->namespaces))
    return 0;
    return 0;
  k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces);
  k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces);
 
 
  /* Check out our super-users.  */
  /* Check out our super-users.  */
  for (value = DECL_NAMESPACE_ASSOCIATIONS (scope); value;
  for (value = DECL_NAMESPACE_ASSOCIATIONS (scope); value;
       value = TREE_CHAIN (value))
       value = TREE_CHAIN (value))
    if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
    if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
      return true;
      return true;
 
 
  /* Also look down into inline namespaces.  */
  /* Also look down into inline namespaces.  */
  for (value = DECL_NAMESPACE_USING (scope); value;
  for (value = DECL_NAMESPACE_USING (scope); value;
       value = TREE_CHAIN (value))
       value = TREE_CHAIN (value))
    if (is_associated_namespace (scope, TREE_PURPOSE (value)))
    if (is_associated_namespace (scope, TREE_PURPOSE (value)))
      if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
      if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
        return true;
        return true;
 
 
  value = namespace_binding (k->name, scope);
  value = namespace_binding (k->name, scope);
  if (!value)
  if (!value)
    return false;
    return false;
 
 
  for (; value; value = OVL_NEXT (value))
  for (; value; value = OVL_NEXT (value))
    {
    {
      /* We don't want to find arbitrary hidden functions via argument
      /* We don't want to find arbitrary hidden functions via argument
         dependent lookup.  We only want to find friends of associated
         dependent lookup.  We only want to find friends of associated
         classes, which we'll do via arg_assoc_class.  */
         classes, which we'll do via arg_assoc_class.  */
      if (hidden_name_p (OVL_CURRENT (value)))
      if (hidden_name_p (OVL_CURRENT (value)))
        continue;
        continue;
 
 
      if (add_function (k, OVL_CURRENT (value)))
      if (add_function (k, OVL_CURRENT (value)))
        return true;
        return true;
    }
    }
 
 
  return false;
  return false;
}
}
 
 
/* Adds everything associated with a template argument to the lookup
/* Adds everything associated with a template argument to the lookup
   structure.  Returns true on error.  */
   structure.  Returns true on error.  */
 
 
static bool
static bool
arg_assoc_template_arg (struct arg_lookup *k, tree arg)
arg_assoc_template_arg (struct arg_lookup *k, tree arg)
{
{
  /* [basic.lookup.koenig]
  /* [basic.lookup.koenig]
 
 
     If T is a template-id, its associated namespaces and classes are
     If T is a template-id, its associated namespaces and classes are
     ... the namespaces and classes associated with the types of the
     ... the namespaces and classes associated with the types of the
     template arguments provided for template type parameters
     template arguments provided for template type parameters
     (excluding template template parameters); the namespaces in which
     (excluding template template parameters); the namespaces in which
     any template template arguments are defined; and the classes in
     any template template arguments are defined; and the classes in
     which any member templates used as template template arguments
     which any member templates used as template template arguments
     are defined.  [Note: non-type template arguments do not
     are defined.  [Note: non-type template arguments do not
     contribute to the set of associated namespaces.  ]  */
     contribute to the set of associated namespaces.  ]  */
 
 
  /* Consider first template template arguments.  */
  /* Consider first template template arguments.  */
  if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
  if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
      || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)
      || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)
    return false;
    return false;
  else if (TREE_CODE (arg) == TEMPLATE_DECL)
  else if (TREE_CODE (arg) == TEMPLATE_DECL)
    {
    {
      tree ctx = CP_DECL_CONTEXT (arg);
      tree ctx = CP_DECL_CONTEXT (arg);
 
 
      /* It's not a member template.  */
      /* It's not a member template.  */
      if (TREE_CODE (ctx) == NAMESPACE_DECL)
      if (TREE_CODE (ctx) == NAMESPACE_DECL)
        return arg_assoc_namespace (k, ctx);
        return arg_assoc_namespace (k, ctx);
      /* Otherwise, it must be member template.  */
      /* Otherwise, it must be member template.  */
      else
      else
        return arg_assoc_class_only (k, ctx);
        return arg_assoc_class_only (k, ctx);
    }
    }
  /* It's an argument pack; handle it recursively.  */
  /* It's an argument pack; handle it recursively.  */
  else if (ARGUMENT_PACK_P (arg))
  else if (ARGUMENT_PACK_P (arg))
    {
    {
      tree args = ARGUMENT_PACK_ARGS (arg);
      tree args = ARGUMENT_PACK_ARGS (arg);
      int i, len = TREE_VEC_LENGTH (args);
      int i, len = TREE_VEC_LENGTH (args);
      for (i = 0; i < len; ++i)
      for (i = 0; i < len; ++i)
        if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, i)))
        if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, i)))
          return true;
          return true;
 
 
      return false;
      return false;
    }
    }
  /* It's not a template template argument, but it is a type template
  /* It's not a template template argument, but it is a type template
     argument.  */
     argument.  */
  else if (TYPE_P (arg))
  else if (TYPE_P (arg))
    return arg_assoc_type (k, arg);
    return arg_assoc_type (k, arg);
  /* It's a non-type template argument.  */
  /* It's a non-type template argument.  */
  else
  else
    return false;
    return false;
}
}
 
 
/* Adds the class and its friends to the lookup structure.
/* Adds the class and its friends to the lookup structure.
   Returns true on error.  */
   Returns true on error.  */
 
 
static bool
static bool
arg_assoc_class_only (struct arg_lookup *k, tree type)
arg_assoc_class_only (struct arg_lookup *k, tree type)
{
{
  tree list, friends, context;
  tree list, friends, context;
 
 
  /* Backend-built structures, such as __builtin_va_list, aren't
  /* Backend-built structures, such as __builtin_va_list, aren't
     affected by all this.  */
     affected by all this.  */
  if (!CLASS_TYPE_P (type))
  if (!CLASS_TYPE_P (type))
    return false;
    return false;
 
 
  context = decl_namespace_context (type);
  context = decl_namespace_context (type);
  if (arg_assoc_namespace (k, context))
  if (arg_assoc_namespace (k, context))
    return true;
    return true;
 
 
  complete_type (type);
  complete_type (type);
 
 
  /* Process friends.  */
  /* Process friends.  */
  for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
  for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
       list = TREE_CHAIN (list))
       list = TREE_CHAIN (list))
    if (k->name == FRIEND_NAME (list))
    if (k->name == FRIEND_NAME (list))
      for (friends = FRIEND_DECLS (list); friends;
      for (friends = FRIEND_DECLS (list); friends;
           friends = TREE_CHAIN (friends))
           friends = TREE_CHAIN (friends))
        {
        {
          tree fn = TREE_VALUE (friends);
          tree fn = TREE_VALUE (friends);
 
 
          /* Only interested in global functions with potentially hidden
          /* Only interested in global functions with potentially hidden
             (i.e. unqualified) declarations.  */
             (i.e. unqualified) declarations.  */
          if (CP_DECL_CONTEXT (fn) != context)
          if (CP_DECL_CONTEXT (fn) != context)
            continue;
            continue;
          /* Template specializations are never found by name lookup.
          /* Template specializations are never found by name lookup.
             (Templates themselves can be found, but not template
             (Templates themselves can be found, but not template
             specializations.)  */
             specializations.)  */
          if (TREE_CODE (fn) == FUNCTION_DECL && DECL_USE_TEMPLATE (fn))
          if (TREE_CODE (fn) == FUNCTION_DECL && DECL_USE_TEMPLATE (fn))
            continue;
            continue;
          if (add_function (k, fn))
          if (add_function (k, fn))
            return true;
            return true;
        }
        }
 
 
  return false;
  return false;
}
}
 
 
/* Adds the class and its bases to the lookup structure.
/* Adds the class and its bases to the lookup structure.
   Returns true on error.  */
   Returns true on error.  */
 
 
static bool
static bool
arg_assoc_bases (struct arg_lookup *k, tree type)
arg_assoc_bases (struct arg_lookup *k, tree type)
{
{
  if (arg_assoc_class_only (k, type))
  if (arg_assoc_class_only (k, type))
    return true;
    return true;
 
 
  if (TYPE_BINFO (type))
  if (TYPE_BINFO (type))
    {
    {
      /* Process baseclasses.  */
      /* Process baseclasses.  */
      tree binfo, base_binfo;
      tree binfo, base_binfo;
      int i;
      int i;
 
 
      for (binfo = TYPE_BINFO (type), i = 0;
      for (binfo = TYPE_BINFO (type), i = 0;
           BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
           BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
        if (arg_assoc_bases (k, BINFO_TYPE (base_binfo)))
        if (arg_assoc_bases (k, BINFO_TYPE (base_binfo)))
          return true;
          return true;
    }
    }
 
 
  return false;
  return false;
}
}
 
 
/* Adds everything associated with a class argument type to the lookup
/* Adds everything associated with a class argument type to the lookup
   structure.  Returns true on error.
   structure.  Returns true on error.
 
 
   If T is a class type (including unions), its associated classes are: the
   If T is a class type (including unions), its associated classes are: the
   class itself; the class of which it is a member, if any; and its direct
   class itself; the class of which it is a member, if any; and its direct
   and indirect base classes. Its associated namespaces are the namespaces
   and indirect base classes. Its associated namespaces are the namespaces
   of which its associated classes are members. Furthermore, if T is a
   of which its associated classes are members. Furthermore, if T is a
   class template specialization, its associated namespaces and classes
   class template specialization, its associated namespaces and classes
   also include: the namespaces and classes associated with the types of
   also include: the namespaces and classes associated with the types of
   the template arguments provided for template type parameters (excluding
   the template arguments provided for template type parameters (excluding
   template template parameters); the namespaces of which any template
   template template parameters); the namespaces of which any template
   template arguments are members; and the classes of which any member
   template arguments are members; and the classes of which any member
   templates used as template template arguments are members. [ Note:
   templates used as template template arguments are members. [ Note:
   non-type template arguments do not contribute to the set of associated
   non-type template arguments do not contribute to the set of associated
   namespaces.  --end note] */
   namespaces.  --end note] */
 
 
static bool
static bool
arg_assoc_class (struct arg_lookup *k, tree type)
arg_assoc_class (struct arg_lookup *k, tree type)
{
{
  tree list;
  tree list;
  int i;
  int i;
 
 
  /* Backend build structures, such as __builtin_va_list, aren't
  /* Backend build structures, such as __builtin_va_list, aren't
     affected by all this.  */
     affected by all this.  */
  if (!CLASS_TYPE_P (type))
  if (!CLASS_TYPE_P (type))
    return false;
    return false;
 
 
  if (purpose_member (type, k->classes))
  if (purpose_member (type, k->classes))
    return false;
    return false;
  k->classes = tree_cons (type, NULL_TREE, k->classes);
  k->classes = tree_cons (type, NULL_TREE, k->classes);
 
 
  if (TYPE_CLASS_SCOPE_P (type)
  if (TYPE_CLASS_SCOPE_P (type)
      && arg_assoc_class_only (k, TYPE_CONTEXT (type)))
      && arg_assoc_class_only (k, TYPE_CONTEXT (type)))
    return true;
    return true;
 
 
  if (arg_assoc_bases (k, type))
  if (arg_assoc_bases (k, type))
    return true;
    return true;
 
 
  /* Process template arguments.  */
  /* Process template arguments.  */
  if (CLASSTYPE_TEMPLATE_INFO (type)
  if (CLASSTYPE_TEMPLATE_INFO (type)
      && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
      && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
    {
    {
      list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
      list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
      for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
      for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
        if (arg_assoc_template_arg (k, TREE_VEC_ELT (list, i)))
        if (arg_assoc_template_arg (k, TREE_VEC_ELT (list, i)))
          return true;
          return true;
    }
    }
 
 
  return false;
  return false;
}
}
 
 
/* Adds everything associated with a given type.
/* Adds everything associated with a given type.
   Returns 1 on error.  */
   Returns 1 on error.  */
 
 
static bool
static bool
arg_assoc_type (struct arg_lookup *k, tree type)
arg_assoc_type (struct arg_lookup *k, tree type)
{
{
  /* As we do not get the type of non-type dependent expressions
  /* As we do not get the type of non-type dependent expressions
     right, we can end up with such things without a type.  */
     right, we can end up with such things without a type.  */
  if (!type)
  if (!type)
    return false;
    return false;
 
 
  if (TYPE_PTRMEM_P (type))
  if (TYPE_PTRMEM_P (type))
    {
    {
      /* Pointer to member: associate class type and value type.  */
      /* Pointer to member: associate class type and value type.  */
      if (arg_assoc_type (k, TYPE_PTRMEM_CLASS_TYPE (type)))
      if (arg_assoc_type (k, TYPE_PTRMEM_CLASS_TYPE (type)))
        return true;
        return true;
      return arg_assoc_type (k, TYPE_PTRMEM_POINTED_TO_TYPE (type));
      return arg_assoc_type (k, TYPE_PTRMEM_POINTED_TO_TYPE (type));
    }
    }
  else switch (TREE_CODE (type))
  else switch (TREE_CODE (type))
    {
    {
    case ERROR_MARK:
    case ERROR_MARK:
      return false;
      return false;
    case VOID_TYPE:
    case VOID_TYPE:
    case INTEGER_TYPE:
    case INTEGER_TYPE:
    case REAL_TYPE:
    case REAL_TYPE:
    case COMPLEX_TYPE:
    case COMPLEX_TYPE:
    case VECTOR_TYPE:
    case VECTOR_TYPE:
    case BOOLEAN_TYPE:
    case BOOLEAN_TYPE:
    case FIXED_POINT_TYPE:
    case FIXED_POINT_TYPE:
    case DECLTYPE_TYPE:
    case DECLTYPE_TYPE:
      return false;
      return false;
    case RECORD_TYPE:
    case RECORD_TYPE:
      if (TYPE_PTRMEMFUNC_P (type))
      if (TYPE_PTRMEMFUNC_P (type))
        return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
        return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
    case UNION_TYPE:
    case UNION_TYPE:
      return arg_assoc_class (k, type);
      return arg_assoc_class (k, type);
    case POINTER_TYPE:
    case POINTER_TYPE:
    case REFERENCE_TYPE:
    case REFERENCE_TYPE:
    case ARRAY_TYPE:
    case ARRAY_TYPE:
      return arg_assoc_type (k, TREE_TYPE (type));
      return arg_assoc_type (k, TREE_TYPE (type));
    case ENUMERAL_TYPE:
    case ENUMERAL_TYPE:
      if (TYPE_CLASS_SCOPE_P (type)
      if (TYPE_CLASS_SCOPE_P (type)
          && arg_assoc_class_only (k, TYPE_CONTEXT (type)))
          && arg_assoc_class_only (k, TYPE_CONTEXT (type)))
        return true;
        return true;
      return arg_assoc_namespace (k, decl_namespace_context (type));
      return arg_assoc_namespace (k, decl_namespace_context (type));
    case METHOD_TYPE:
    case METHOD_TYPE:
      /* The basetype is referenced in the first arg type, so just
      /* The basetype is referenced in the first arg type, so just
         fall through.  */
         fall through.  */
    case FUNCTION_TYPE:
    case FUNCTION_TYPE:
      /* Associate the parameter types.  */
      /* Associate the parameter types.  */
      if (arg_assoc_args (k, TYPE_ARG_TYPES (type)))
      if (arg_assoc_args (k, TYPE_ARG_TYPES (type)))
        return true;
        return true;
      /* Associate the return type.  */
      /* Associate the return type.  */
      return arg_assoc_type (k, TREE_TYPE (type));
      return arg_assoc_type (k, TREE_TYPE (type));
    case TEMPLATE_TYPE_PARM:
    case TEMPLATE_TYPE_PARM:
    case BOUND_TEMPLATE_TEMPLATE_PARM:
    case BOUND_TEMPLATE_TEMPLATE_PARM:
      return false;
      return false;
    case TYPENAME_TYPE:
    case TYPENAME_TYPE:
      return false;
      return false;
    case LANG_TYPE:
    case LANG_TYPE:
      gcc_assert (type == unknown_type_node
      gcc_assert (type == unknown_type_node
                  || type == init_list_type_node);
                  || type == init_list_type_node);
      return false;
      return false;
    case TYPE_PACK_EXPANSION:
    case TYPE_PACK_EXPANSION:
      return arg_assoc_type (k, PACK_EXPANSION_PATTERN (type));
      return arg_assoc_type (k, PACK_EXPANSION_PATTERN (type));
 
 
    default:
    default:
      gcc_unreachable ();
      gcc_unreachable ();
    }
    }
  return false;
  return false;
}
}
 
 
/* Adds everything associated with arguments.  Returns true on error.  */
/* Adds everything associated with arguments.  Returns true on error.  */
 
 
static bool
static bool
arg_assoc_args (struct arg_lookup *k, tree args)
arg_assoc_args (struct arg_lookup *k, tree args)
{
{
  for (; args; args = TREE_CHAIN (args))
  for (; args; args = TREE_CHAIN (args))
    if (arg_assoc (k, TREE_VALUE (args)))
    if (arg_assoc (k, TREE_VALUE (args)))
      return true;
      return true;
  return false;
  return false;
}
}
 
 
/* Adds everything associated with an argument vector.  Returns true
/* Adds everything associated with an argument vector.  Returns true
   on error.  */
   on error.  */
 
 
static bool
static bool
arg_assoc_args_vec (struct arg_lookup *k, VEC(tree,gc) *args)
arg_assoc_args_vec (struct arg_lookup *k, VEC(tree,gc) *args)
{
{
  unsigned int ix;
  unsigned int ix;
  tree arg;
  tree arg;
 
 
  for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
  for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
    if (arg_assoc (k, arg))
    if (arg_assoc (k, arg))
      return true;
      return true;
  return false;
  return false;
}
}
 
 
/* Adds everything associated with a given tree_node.  Returns 1 on error.  */
/* Adds everything associated with a given tree_node.  Returns 1 on error.  */
 
 
static bool
static bool
arg_assoc (struct arg_lookup *k, tree n)
arg_assoc (struct arg_lookup *k, tree n)
{
{
  if (n == error_mark_node)
  if (n == error_mark_node)
    return false;
    return false;
 
 
  if (TYPE_P (n))
  if (TYPE_P (n))
    return arg_assoc_type (k, n);
    return arg_assoc_type (k, n);
 
 
  if (! type_unknown_p (n))
  if (! type_unknown_p (n))
    return arg_assoc_type (k, TREE_TYPE (n));
    return arg_assoc_type (k, TREE_TYPE (n));
 
 
  if (TREE_CODE (n) == ADDR_EXPR)
  if (TREE_CODE (n) == ADDR_EXPR)
    n = TREE_OPERAND (n, 0);
    n = TREE_OPERAND (n, 0);
  if (TREE_CODE (n) == COMPONENT_REF)
  if (TREE_CODE (n) == COMPONENT_REF)
    n = TREE_OPERAND (n, 1);
    n = TREE_OPERAND (n, 1);
  if (TREE_CODE (n) == OFFSET_REF)
  if (TREE_CODE (n) == OFFSET_REF)
    n = TREE_OPERAND (n, 1);
    n = TREE_OPERAND (n, 1);
  while (TREE_CODE (n) == TREE_LIST)
  while (TREE_CODE (n) == TREE_LIST)
    n = TREE_VALUE (n);
    n = TREE_VALUE (n);
  if (TREE_CODE (n) == BASELINK)
  if (TREE_CODE (n) == BASELINK)
    n = BASELINK_FUNCTIONS (n);
    n = BASELINK_FUNCTIONS (n);
 
 
  if (TREE_CODE (n) == FUNCTION_DECL)
  if (TREE_CODE (n) == FUNCTION_DECL)
    return arg_assoc_type (k, TREE_TYPE (n));
    return arg_assoc_type (k, TREE_TYPE (n));
  if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
  if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
    {
    {
      /* The working paper doesn't currently say how to handle template-id
      /* The working paper doesn't currently say how to handle template-id
         arguments.  The sensible thing would seem to be to handle the list
         arguments.  The sensible thing would seem to be to handle the list
         of template candidates like a normal overload set, and handle the
         of template candidates like a normal overload set, and handle the
         template arguments like we do for class template
         template arguments like we do for class template
         specializations.  */
         specializations.  */
      tree templ = TREE_OPERAND (n, 0);
      tree templ = TREE_OPERAND (n, 0);
      tree args = TREE_OPERAND (n, 1);
      tree args = TREE_OPERAND (n, 1);
      int ix;
      int ix;
 
 
      /* First the templates.  */
      /* First the templates.  */
      if (arg_assoc (k, templ))
      if (arg_assoc (k, templ))
        return true;
        return true;
 
 
      /* Now the arguments.  */
      /* Now the arguments.  */
      if (args)
      if (args)
        for (ix = TREE_VEC_LENGTH (args); ix--;)
        for (ix = TREE_VEC_LENGTH (args); ix--;)
          if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
          if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
            return true;
            return true;
    }
    }
  else if (TREE_CODE (n) == OVERLOAD)
  else if (TREE_CODE (n) == OVERLOAD)
    {
    {
      for (; n; n = OVL_CHAIN (n))
      for (; n; n = OVL_CHAIN (n))
        if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n))))
        if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n))))
          return true;
          return true;
    }
    }
 
 
  return false;
  return false;
}
}
 
 
/* Performs Koenig lookup depending on arguments, where fns
/* Performs Koenig lookup depending on arguments, where fns
   are the functions found in normal lookup.  */
   are the functions found in normal lookup.  */
 
 
tree
tree
lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args)
lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args)
{
{
  struct arg_lookup k;
  struct arg_lookup k;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
 
 
  /* Remove any hidden friend functions from the list of functions
  /* Remove any hidden friend functions from the list of functions
     found so far.  They will be added back by arg_assoc_class as
     found so far.  They will be added back by arg_assoc_class as
     appropriate.  */
     appropriate.  */
  fns = remove_hidden_names (fns);
  fns = remove_hidden_names (fns);
 
 
  k.name = name;
  k.name = name;
  k.args = args;
  k.args = args;
  k.functions = fns;
  k.functions = fns;
  k.classes = NULL_TREE;
  k.classes = NULL_TREE;
 
 
  /* We previously performed an optimization here by setting
  /* We previously performed an optimization here by setting
     NAMESPACES to the current namespace when it was safe. However, DR
     NAMESPACES to the current namespace when it was safe. However, DR
     164 says that namespaces that were already searched in the first
     164 says that namespaces that were already searched in the first
     stage of template processing are searched again (potentially
     stage of template processing are searched again (potentially
     picking up later definitions) in the second stage. */
     picking up later definitions) in the second stage. */
  k.namespaces = NULL_TREE;
  k.namespaces = NULL_TREE;
 
 
  arg_assoc_args_vec (&k, args);
  arg_assoc_args_vec (&k, args);
 
 
  fns = k.functions;
  fns = k.functions;
 
 
  if (fns
  if (fns
      && TREE_CODE (fns) != VAR_DECL
      && TREE_CODE (fns) != VAR_DECL
      && !is_overloaded_fn (fns))
      && !is_overloaded_fn (fns))
    {
    {
      error ("argument dependent lookup finds %q+D", fns);
      error ("argument dependent lookup finds %q+D", fns);
      error ("  in call to %qD", name);
      error ("  in call to %qD", name);
      fns = error_mark_node;
      fns = error_mark_node;
    }
    }
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fns);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fns);
}
}
 
 
/* Add namespace to using_directives. Return NULL_TREE if nothing was
/* Add namespace to using_directives. Return NULL_TREE if nothing was
   changed (i.e. there was already a directive), or the fresh
   changed (i.e. there was already a directive), or the fresh
   TREE_LIST otherwise.  */
   TREE_LIST otherwise.  */
 
 
static tree
static tree
push_using_directive (tree used)
push_using_directive (tree used)
{
{
  tree ud = current_binding_level->using_directives;
  tree ud = current_binding_level->using_directives;
  tree iter, ancestor;
  tree iter, ancestor;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  /* Check if we already have this.  */
  /* Check if we already have this.  */
  if (purpose_member (used, ud) != NULL_TREE)
  if (purpose_member (used, ud) != NULL_TREE)
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
 
 
  ancestor = namespace_ancestor (current_decl_namespace (), used);
  ancestor = namespace_ancestor (current_decl_namespace (), used);
  ud = current_binding_level->using_directives;
  ud = current_binding_level->using_directives;
  ud = tree_cons (used, ancestor, ud);
  ud = tree_cons (used, ancestor, ud);
  current_binding_level->using_directives = ud;
  current_binding_level->using_directives = ud;
 
 
  /* Recursively add all namespaces used.  */
  /* Recursively add all namespaces used.  */
  for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
  for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
    push_using_directive (TREE_PURPOSE (iter));
    push_using_directive (TREE_PURPOSE (iter));
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ud);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ud);
}
}
 
 
/* The type TYPE is being declared.  If it is a class template, or a
/* The type TYPE is being declared.  If it is a class template, or a
   specialization of a class template, do any processing required and
   specialization of a class template, do any processing required and
   perform error-checking.  If IS_FRIEND is nonzero, this TYPE is
   perform error-checking.  If IS_FRIEND is nonzero, this TYPE is
   being declared a friend.  B is the binding level at which this TYPE
   being declared a friend.  B is the binding level at which this TYPE
   should be bound.
   should be bound.
 
 
   Returns the TYPE_DECL for TYPE, which may have been altered by this
   Returns the TYPE_DECL for TYPE, which may have been altered by this
   processing.  */
   processing.  */
 
 
static tree
static tree
maybe_process_template_type_declaration (tree type, int is_friend,
maybe_process_template_type_declaration (tree type, int is_friend,
                                         cxx_scope *b)
                                         cxx_scope *b)
{
{
  tree decl = TYPE_NAME (type);
  tree decl = TYPE_NAME (type);
 
 
  if (processing_template_parmlist)
  if (processing_template_parmlist)
    /* You can't declare a new template type in a template parameter
    /* You can't declare a new template type in a template parameter
       list.  But, you can declare a non-template type:
       list.  But, you can declare a non-template type:
 
 
         template <class A*> struct S;
         template <class A*> struct S;
 
 
       is a forward-declaration of `A'.  */
       is a forward-declaration of `A'.  */
    ;
    ;
  else if (b->kind == sk_namespace
  else if (b->kind == sk_namespace
           && current_binding_level->kind != sk_namespace)
           && current_binding_level->kind != sk_namespace)
    /* If this new type is being injected into a containing scope,
    /* If this new type is being injected into a containing scope,
       then it's not a template type.  */
       then it's not a template type.  */
    ;
    ;
  else
  else
    {
    {
      gcc_assert (MAYBE_CLASS_TYPE_P (type)
      gcc_assert (MAYBE_CLASS_TYPE_P (type)
                  || TREE_CODE (type) == ENUMERAL_TYPE);
                  || TREE_CODE (type) == ENUMERAL_TYPE);
 
 
      if (processing_template_decl)
      if (processing_template_decl)
        {
        {
          /* This may change after the call to
          /* This may change after the call to
             push_template_decl_real, but we want the original value.  */
             push_template_decl_real, but we want the original value.  */
          tree name = DECL_NAME (decl);
          tree name = DECL_NAME (decl);
 
 
          decl = push_template_decl_real (decl, is_friend);
          decl = push_template_decl_real (decl, is_friend);
          if (decl == error_mark_node)
          if (decl == error_mark_node)
            return error_mark_node;
            return error_mark_node;
 
 
          /* If the current binding level is the binding level for the
          /* If the current binding level is the binding level for the
             template parameters (see the comment in
             template parameters (see the comment in
             begin_template_parm_list) and the enclosing level is a class
             begin_template_parm_list) and the enclosing level is a class
             scope, and we're not looking at a friend, push the
             scope, and we're not looking at a friend, push the
             declaration of the member class into the class scope.  In the
             declaration of the member class into the class scope.  In the
             friend case, push_template_decl will already have put the
             friend case, push_template_decl will already have put the
             friend into global scope, if appropriate.  */
             friend into global scope, if appropriate.  */
          if (TREE_CODE (type) != ENUMERAL_TYPE
          if (TREE_CODE (type) != ENUMERAL_TYPE
              && !is_friend && b->kind == sk_template_parms
              && !is_friend && b->kind == sk_template_parms
              && b->level_chain->kind == sk_class)
              && b->level_chain->kind == sk_class)
            {
            {
              finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
              finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
 
 
              if (!COMPLETE_TYPE_P (current_class_type))
              if (!COMPLETE_TYPE_P (current_class_type))
                {
                {
                  maybe_add_class_template_decl_list (current_class_type,
                  maybe_add_class_template_decl_list (current_class_type,
                                                      type, /*friend_p=*/0);
                                                      type, /*friend_p=*/0);
                  /* Put this UTD in the table of UTDs for the class.  */
                  /* Put this UTD in the table of UTDs for the class.  */
                  if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
                  if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
                    CLASSTYPE_NESTED_UTDS (current_class_type) =
                    CLASSTYPE_NESTED_UTDS (current_class_type) =
                      binding_table_new (SCOPE_DEFAULT_HT_SIZE);
                      binding_table_new (SCOPE_DEFAULT_HT_SIZE);
 
 
                  binding_table_insert
                  binding_table_insert
                    (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
                    (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
                }
                }
            }
            }
        }
        }
    }
    }
 
 
  return decl;
  return decl;
}
}
 
 
/* Push a tag name NAME for struct/class/union/enum type TYPE.  In case
/* Push a tag name NAME for struct/class/union/enum type TYPE.  In case
   that the NAME is a class template, the tag is processed but not pushed.
   that the NAME is a class template, the tag is processed but not pushed.
 
 
   The pushed scope depend on the SCOPE parameter:
   The pushed scope depend on the SCOPE parameter:
   - When SCOPE is TS_CURRENT, put it into the inner-most non-sk_cleanup
   - When SCOPE is TS_CURRENT, put it into the inner-most non-sk_cleanup
     scope.
     scope.
   - When SCOPE is TS_GLOBAL, put it in the inner-most non-class and
   - When SCOPE is TS_GLOBAL, put it in the inner-most non-class and
     non-template-parameter scope.  This case is needed for forward
     non-template-parameter scope.  This case is needed for forward
     declarations.
     declarations.
   - When SCOPE is TS_WITHIN_ENCLOSING_NON_CLASS, this is similar to
   - When SCOPE is TS_WITHIN_ENCLOSING_NON_CLASS, this is similar to
     TS_GLOBAL case except that names within template-parameter scopes
     TS_GLOBAL case except that names within template-parameter scopes
     are not pushed at all.
     are not pushed at all.
 
 
   Returns TYPE upon success and ERROR_MARK_NODE otherwise.  */
   Returns TYPE upon success and ERROR_MARK_NODE otherwise.  */
 
 
tree
tree
pushtag (tree name, tree type, tag_scope scope)
pushtag (tree name, tree type, tag_scope scope)
{
{
  struct cp_binding_level *b;
  struct cp_binding_level *b;
  tree decl;
  tree decl;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  b = current_binding_level;
  b = current_binding_level;
  while (/* Cleanup scopes are not scopes from the point of view of
  while (/* Cleanup scopes are not scopes from the point of view of
            the language.  */
            the language.  */
         b->kind == sk_cleanup
         b->kind == sk_cleanup
         /* Neither are function parameter scopes.  */
         /* Neither are function parameter scopes.  */
         || b->kind == sk_function_parms
         || b->kind == sk_function_parms
         /* Neither are the scopes used to hold template parameters
         /* Neither are the scopes used to hold template parameters
            for an explicit specialization.  For an ordinary template
            for an explicit specialization.  For an ordinary template
            declaration, these scopes are not scopes from the point of
            declaration, these scopes are not scopes from the point of
            view of the language.  */
            view of the language.  */
         || (b->kind == sk_template_parms
         || (b->kind == sk_template_parms
             && (b->explicit_spec_p || scope == ts_global))
             && (b->explicit_spec_p || scope == ts_global))
         || (b->kind == sk_class
         || (b->kind == sk_class
             && (scope != ts_current
             && (scope != ts_current
                 /* We may be defining a new type in the initializer
                 /* We may be defining a new type in the initializer
                    of a static member variable. We allow this when
                    of a static member variable. We allow this when
                    not pedantic, and it is particularly useful for
                    not pedantic, and it is particularly useful for
                    type punning via an anonymous union.  */
                    type punning via an anonymous union.  */
                 || COMPLETE_TYPE_P (b->this_entity))))
                 || COMPLETE_TYPE_P (b->this_entity))))
    b = b->level_chain;
    b = b->level_chain;
 
 
  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
 
 
  /* Do C++ gratuitous typedefing.  */
  /* Do C++ gratuitous typedefing.  */
  if (IDENTIFIER_TYPE_VALUE (name) != type)
  if (IDENTIFIER_TYPE_VALUE (name) != type)
    {
    {
      tree tdef;
      tree tdef;
      int in_class = 0;
      int in_class = 0;
      tree context = TYPE_CONTEXT (type);
      tree context = TYPE_CONTEXT (type);
 
 
      if (! context)
      if (! context)
        {
        {
          tree cs = current_scope ();
          tree cs = current_scope ();
 
 
          if (scope == ts_current
          if (scope == ts_current
              || (cs && TREE_CODE (cs) == FUNCTION_DECL))
              || (cs && TREE_CODE (cs) == FUNCTION_DECL))
            context = cs;
            context = cs;
          else if (cs != NULL_TREE && TYPE_P (cs))
          else if (cs != NULL_TREE && TYPE_P (cs))
            /* When declaring a friend class of a local class, we want
            /* When declaring a friend class of a local class, we want
               to inject the newly named class into the scope
               to inject the newly named class into the scope
               containing the local class, not the namespace
               containing the local class, not the namespace
               scope.  */
               scope.  */
            context = decl_function_context (get_type_decl (cs));
            context = decl_function_context (get_type_decl (cs));
        }
        }
      if (!context)
      if (!context)
        context = current_namespace;
        context = current_namespace;
 
 
      if (b->kind == sk_class
      if (b->kind == sk_class
          || (b->kind == sk_template_parms
          || (b->kind == sk_template_parms
              && b->level_chain->kind == sk_class))
              && b->level_chain->kind == sk_class))
        in_class = 1;
        in_class = 1;
 
 
      if (current_lang_name == lang_name_java)
      if (current_lang_name == lang_name_java)
        TYPE_FOR_JAVA (type) = 1;
        TYPE_FOR_JAVA (type) = 1;
 
 
      tdef = create_implicit_typedef (name, type);
      tdef = create_implicit_typedef (name, type);
      DECL_CONTEXT (tdef) = FROB_CONTEXT (context);
      DECL_CONTEXT (tdef) = FROB_CONTEXT (context);
      if (scope == ts_within_enclosing_non_class)
      if (scope == ts_within_enclosing_non_class)
        {
        {
          /* This is a friend.  Make this TYPE_DECL node hidden from
          /* This is a friend.  Make this TYPE_DECL node hidden from
             ordinary name lookup.  Its corresponding TEMPLATE_DECL
             ordinary name lookup.  Its corresponding TEMPLATE_DECL
             will be marked in push_template_decl_real.  */
             will be marked in push_template_decl_real.  */
          retrofit_lang_decl (tdef);
          retrofit_lang_decl (tdef);
          DECL_ANTICIPATED (tdef) = 1;
          DECL_ANTICIPATED (tdef) = 1;
          DECL_FRIEND_P (tdef) = 1;
          DECL_FRIEND_P (tdef) = 1;
        }
        }
 
 
      decl = maybe_process_template_type_declaration
      decl = maybe_process_template_type_declaration
        (type, scope == ts_within_enclosing_non_class, b);
        (type, scope == ts_within_enclosing_non_class, b);
      if (decl == error_mark_node)
      if (decl == error_mark_node)
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
 
 
      if (b->kind == sk_class)
      if (b->kind == sk_class)
        {
        {
          if (!TYPE_BEING_DEFINED (current_class_type))
          if (!TYPE_BEING_DEFINED (current_class_type))
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
 
          if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
          if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
            /* Put this TYPE_DECL on the TYPE_FIELDS list for the
            /* Put this TYPE_DECL on the TYPE_FIELDS list for the
               class.  But if it's a member template class, we want
               class.  But if it's a member template class, we want
               the TEMPLATE_DECL, not the TYPE_DECL, so this is done
               the TEMPLATE_DECL, not the TYPE_DECL, so this is done
               later.  */
               later.  */
            finish_member_declaration (decl);
            finish_member_declaration (decl);
          else
          else
            pushdecl_class_level (decl);
            pushdecl_class_level (decl);
        }
        }
      else if (b->kind != sk_template_parms)
      else if (b->kind != sk_template_parms)
        {
        {
          decl = pushdecl_with_scope (decl, b, /*is_friend=*/false);
          decl = pushdecl_with_scope (decl, b, /*is_friend=*/false);
          if (decl == error_mark_node)
          if (decl == error_mark_node)
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
        }
        }
 
 
      if (! in_class)
      if (! in_class)
        set_identifier_type_value_with_scope (name, tdef, b);
        set_identifier_type_value_with_scope (name, tdef, b);
 
 
      TYPE_CONTEXT (type) = DECL_CONTEXT (decl);
      TYPE_CONTEXT (type) = DECL_CONTEXT (decl);
 
 
      /* If this is a local class, keep track of it.  We need this
      /* If this is a local class, keep track of it.  We need this
         information for name-mangling, and so that it is possible to
         information for name-mangling, and so that it is possible to
         find all function definitions in a translation unit in a
         find all function definitions in a translation unit in a
         convenient way.  (It's otherwise tricky to find a member
         convenient way.  (It's otherwise tricky to find a member
         function definition it's only pointed to from within a local
         function definition it's only pointed to from within a local
         class.)  */
         class.)  */
      if (TYPE_CONTEXT (type)
      if (TYPE_CONTEXT (type)
          && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL)
          && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL)
        VEC_safe_push (tree, gc, local_classes, type);
        VEC_safe_push (tree, gc, local_classes, type);
    }
    }
  if (b->kind == sk_class
  if (b->kind == sk_class
      && !COMPLETE_TYPE_P (current_class_type))
      && !COMPLETE_TYPE_P (current_class_type))
    {
    {
      maybe_add_class_template_decl_list (current_class_type,
      maybe_add_class_template_decl_list (current_class_type,
                                          type, /*friend_p=*/0);
                                          type, /*friend_p=*/0);
 
 
      if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
      if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
        CLASSTYPE_NESTED_UTDS (current_class_type)
        CLASSTYPE_NESTED_UTDS (current_class_type)
          = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
          = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
 
 
      binding_table_insert
      binding_table_insert
        (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
        (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
    }
    }
 
 
  decl = TYPE_NAME (type);
  decl = TYPE_NAME (type);
  gcc_assert (TREE_CODE (decl) == TYPE_DECL);
  gcc_assert (TREE_CODE (decl) == TYPE_DECL);
 
 
  /* Set type visibility now if this is a forward declaration.  */
  /* Set type visibility now if this is a forward declaration.  */
  TREE_PUBLIC (decl) = 1;
  TREE_PUBLIC (decl) = 1;
  determine_visibility (decl);
  determine_visibility (decl);
 
 
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
}
}


/* Subroutines for reverting temporarily to top-level for instantiation
/* Subroutines for reverting temporarily to top-level for instantiation
   of templates and such.  We actually need to clear out the class- and
   of templates and such.  We actually need to clear out the class- and
   local-value slots of all identifiers, so that only the global values
   local-value slots of all identifiers, so that only the global values
   are at all visible.  Simply setting current_binding_level to the global
   are at all visible.  Simply setting current_binding_level to the global
   scope isn't enough, because more binding levels may be pushed.  */
   scope isn't enough, because more binding levels may be pushed.  */
struct saved_scope *scope_chain;
struct saved_scope *scope_chain;
 
 
/* If ID has not already been marked, add an appropriate binding to
/* If ID has not already been marked, add an appropriate binding to
   *OLD_BINDINGS.  */
   *OLD_BINDINGS.  */
 
 
static void
static void
store_binding (tree id, VEC(cxx_saved_binding,gc) **old_bindings)
store_binding (tree id, VEC(cxx_saved_binding,gc) **old_bindings)
{
{
  cxx_saved_binding *saved;
  cxx_saved_binding *saved;
 
 
  if (!id || !IDENTIFIER_BINDING (id))
  if (!id || !IDENTIFIER_BINDING (id))
    return;
    return;
 
 
  if (IDENTIFIER_MARKED (id))
  if (IDENTIFIER_MARKED (id))
    return;
    return;
 
 
  IDENTIFIER_MARKED (id) = 1;
  IDENTIFIER_MARKED (id) = 1;
 
 
  saved = VEC_safe_push (cxx_saved_binding, gc, *old_bindings, NULL);
  saved = VEC_safe_push (cxx_saved_binding, gc, *old_bindings, NULL);
  saved->identifier = id;
  saved->identifier = id;
  saved->binding = IDENTIFIER_BINDING (id);
  saved->binding = IDENTIFIER_BINDING (id);
  saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
  saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
  IDENTIFIER_BINDING (id) = NULL;
  IDENTIFIER_BINDING (id) = NULL;
}
}
 
 
static void
static void
store_bindings (tree names, VEC(cxx_saved_binding,gc) **old_bindings)
store_bindings (tree names, VEC(cxx_saved_binding,gc) **old_bindings)
{
{
  tree t;
  tree t;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  for (t = names; t; t = TREE_CHAIN (t))
  for (t = names; t; t = TREE_CHAIN (t))
    {
    {
      tree id;
      tree id;
 
 
      if (TREE_CODE (t) == TREE_LIST)
      if (TREE_CODE (t) == TREE_LIST)
        id = TREE_PURPOSE (t);
        id = TREE_PURPOSE (t);
      else
      else
        id = DECL_NAME (t);
        id = DECL_NAME (t);
 
 
      store_binding (id, old_bindings);
      store_binding (id, old_bindings);
    }
    }
  timevar_pop (TV_NAME_LOOKUP);
  timevar_pop (TV_NAME_LOOKUP);
}
}
 
 
/* Like store_bindings, but NAMES is a vector of cp_class_binding
/* Like store_bindings, but NAMES is a vector of cp_class_binding
   objects, rather than a TREE_LIST.  */
   objects, rather than a TREE_LIST.  */
 
 
static void
static void
store_class_bindings (VEC(cp_class_binding,gc) *names,
store_class_bindings (VEC(cp_class_binding,gc) *names,
                      VEC(cxx_saved_binding,gc) **old_bindings)
                      VEC(cxx_saved_binding,gc) **old_bindings)
{
{
  size_t i;
  size_t i;
  cp_class_binding *cb;
  cp_class_binding *cb;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  for (i = 0; VEC_iterate(cp_class_binding, names, i, cb); ++i)
  for (i = 0; VEC_iterate(cp_class_binding, names, i, cb); ++i)
    store_binding (cb->identifier, old_bindings);
    store_binding (cb->identifier, old_bindings);
  timevar_pop (TV_NAME_LOOKUP);
  timevar_pop (TV_NAME_LOOKUP);
}
}
 
 
void
void
push_to_top_level (void)
push_to_top_level (void)
{
{
  struct saved_scope *s;
  struct saved_scope *s;
  struct cp_binding_level *b;
  struct cp_binding_level *b;
  cxx_saved_binding *sb;
  cxx_saved_binding *sb;
  size_t i;
  size_t i;
  bool need_pop;
  bool need_pop;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  s = GGC_CNEW (struct saved_scope);
  s = GGC_CNEW (struct saved_scope);
 
 
  b = scope_chain ? current_binding_level : 0;
  b = scope_chain ? current_binding_level : 0;
 
 
  /* If we're in the middle of some function, save our state.  */
  /* If we're in the middle of some function, save our state.  */
  if (cfun)
  if (cfun)
    {
    {
      need_pop = true;
      need_pop = true;
      push_function_context ();
      push_function_context ();
    }
    }
  else
  else
    need_pop = false;
    need_pop = false;
 
 
  if (scope_chain && previous_class_level)
  if (scope_chain && previous_class_level)
    store_class_bindings (previous_class_level->class_shadowed,
    store_class_bindings (previous_class_level->class_shadowed,
                          &s->old_bindings);
                          &s->old_bindings);
 
 
  /* Have to include the global scope, because class-scope decls
  /* Have to include the global scope, because class-scope decls
     aren't listed anywhere useful.  */
     aren't listed anywhere useful.  */
  for (; b; b = b->level_chain)
  for (; b; b = b->level_chain)
    {
    {
      tree t;
      tree t;
 
 
      /* Template IDs are inserted into the global level. If they were
      /* Template IDs are inserted into the global level. If they were
         inserted into namespace level, finish_file wouldn't find them
         inserted into namespace level, finish_file wouldn't find them
         when doing pending instantiations. Therefore, don't stop at
         when doing pending instantiations. Therefore, don't stop at
         namespace level, but continue until :: .  */
         namespace level, but continue until :: .  */
      if (global_scope_p (b))
      if (global_scope_p (b))
        break;
        break;
 
 
      store_bindings (b->names, &s->old_bindings);
      store_bindings (b->names, &s->old_bindings);
      /* We also need to check class_shadowed to save class-level type
      /* We also need to check class_shadowed to save class-level type
         bindings, since pushclass doesn't fill in b->names.  */
         bindings, since pushclass doesn't fill in b->names.  */
      if (b->kind == sk_class)
      if (b->kind == sk_class)
        store_class_bindings (b->class_shadowed, &s->old_bindings);
        store_class_bindings (b->class_shadowed, &s->old_bindings);
 
 
      /* Unwind type-value slots back to top level.  */
      /* Unwind type-value slots back to top level.  */
      for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
      for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
        SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));
        SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));
    }
    }
 
 
  for (i = 0; VEC_iterate (cxx_saved_binding, s->old_bindings, i, sb); ++i)
  for (i = 0; VEC_iterate (cxx_saved_binding, s->old_bindings, i, sb); ++i)
    IDENTIFIER_MARKED (sb->identifier) = 0;
    IDENTIFIER_MARKED (sb->identifier) = 0;
 
 
  s->prev = scope_chain;
  s->prev = scope_chain;
  s->bindings = b;
  s->bindings = b;
  s->need_pop_function_context = need_pop;
  s->need_pop_function_context = need_pop;
  s->function_decl = current_function_decl;
  s->function_decl = current_function_decl;
  s->unevaluated_operand = cp_unevaluated_operand;
  s->unevaluated_operand = cp_unevaluated_operand;
  s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
  s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
 
 
  scope_chain = s;
  scope_chain = s;
  current_function_decl = NULL_TREE;
  current_function_decl = NULL_TREE;
  current_lang_base = VEC_alloc (tree, gc, 10);
  current_lang_base = VEC_alloc (tree, gc, 10);
  current_lang_name = lang_name_cplusplus;
  current_lang_name = lang_name_cplusplus;
  current_namespace = global_namespace;
  current_namespace = global_namespace;
  push_class_stack ();
  push_class_stack ();
  cp_unevaluated_operand = 0;
  cp_unevaluated_operand = 0;
  c_inhibit_evaluation_warnings = 0;
  c_inhibit_evaluation_warnings = 0;
  timevar_pop (TV_NAME_LOOKUP);
  timevar_pop (TV_NAME_LOOKUP);
}
}
 
 
void
void
pop_from_top_level (void)
pop_from_top_level (void)
{
{
  struct saved_scope *s = scope_chain;
  struct saved_scope *s = scope_chain;
  cxx_saved_binding *saved;
  cxx_saved_binding *saved;
  size_t i;
  size_t i;
 
 
  timevar_push (TV_NAME_LOOKUP);
  timevar_push (TV_NAME_LOOKUP);
  /* Clear out class-level bindings cache.  */
  /* Clear out class-level bindings cache.  */
  if (previous_class_level)
  if (previous_class_level)
    invalidate_class_lookup_cache ();
    invalidate_class_lookup_cache ();
  pop_class_stack ();
  pop_class_stack ();
 
 
  current_lang_base = 0;
  current_lang_base = 0;
 
 
  scope_chain = s->prev;
  scope_chain = s->prev;
  for (i = 0; VEC_iterate (cxx_saved_binding, s->old_bindings, i, saved); ++i)
  for (i = 0; VEC_iterate (cxx_saved_binding, s->old_bindings, i, saved); ++i)
    {
    {
      tree id = saved->identifier;
      tree id = saved->identifier;
 
 
      IDENTIFIER_BINDING (id) = saved->binding;
      IDENTIFIER_BINDING (id) = saved->binding;
      SET_IDENTIFIER_TYPE_VALUE (id, saved->real_type_value);
      SET_IDENTIFIER_TYPE_VALUE (id, saved->real_type_value);
    }
    }
 
 
  /* If we were in the middle of compiling a function, restore our
  /* If we were in the middle of compiling a function, restore our
     state.  */
     state.  */
  if (s->need_pop_function_context)
  if (s->need_pop_function_context)
    pop_function_context ();
    pop_function_context ();
  current_function_decl = s->function_decl;
  current_function_decl = s->function_decl;
  cp_unevaluated_operand = s->unevaluated_operand;
  cp_unevaluated_operand = s->unevaluated_operand;
  c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings;
  c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings;
  timevar_pop (TV_NAME_LOOKUP);
  timevar_pop (TV_NAME_LOOKUP);
}
}
 
 
/* Pop off extraneous binding levels left over due to syntax errors.
/* Pop off extraneous binding levels left over due to syntax errors.
 
 
   We don't pop past namespaces, as they might be valid.  */
   We don't pop past namespaces, as they might be valid.  */
 
 
void
void
pop_everything (void)
pop_everything (void)
{
{
  if (ENABLE_SCOPE_CHECKING)
  if (ENABLE_SCOPE_CHECKING)
    verbatim ("XXX entering pop_everything ()\n");
    verbatim ("XXX entering pop_everything ()\n");
  while (!toplevel_bindings_p ())
  while (!toplevel_bindings_p ())
    {
    {
      if (current_binding_level->kind == sk_class)
      if (current_binding_level->kind == sk_class)
        pop_nested_class ();
        pop_nested_class ();
      else
      else
        poplevel (0, 0, 0);
        poplevel (0, 0, 0);
    }
    }
  if (ENABLE_SCOPE_CHECKING)
  if (ENABLE_SCOPE_CHECKING)
    verbatim ("XXX leaving pop_everything ()\n");
    verbatim ("XXX leaving pop_everything ()\n");
}
}
 
 
/* Emit debugging information for using declarations and directives.
/* Emit debugging information for using declarations and directives.
   If input tree is overloaded fn then emit debug info for all
   If input tree is overloaded fn then emit debug info for all
   candidates.  */
   candidates.  */
 
 
void
void
cp_emit_debug_info_for_using (tree t, tree context)
cp_emit_debug_info_for_using (tree t, tree context)
{
{
  /* Don't try to emit any debug information if we have errors.  */
  /* Don't try to emit any debug information if we have errors.  */
  if (sorrycount || errorcount)
  if (sorrycount || errorcount)
    return;
    return;
 
 
  /* Ignore this FUNCTION_DECL if it refers to a builtin declaration
  /* Ignore this FUNCTION_DECL if it refers to a builtin declaration
     of a builtin function.  */
     of a builtin function.  */
  if (TREE_CODE (t) == FUNCTION_DECL
  if (TREE_CODE (t) == FUNCTION_DECL
      && DECL_EXTERNAL (t)
      && DECL_EXTERNAL (t)
      && DECL_BUILT_IN (t))
      && DECL_BUILT_IN (t))
    return;
    return;
 
 
  /* Do not supply context to imported_module_or_decl, if
  /* Do not supply context to imported_module_or_decl, if
     it is a global namespace.  */
     it is a global namespace.  */
  if (context == global_namespace)
  if (context == global_namespace)
    context = NULL_TREE;
    context = NULL_TREE;
 
 
  if (BASELINK_P (t))
  if (BASELINK_P (t))
    t = BASELINK_FUNCTIONS (t);
    t = BASELINK_FUNCTIONS (t);
 
 
  /* FIXME: Handle TEMPLATE_DECLs.  */
  /* FIXME: Handle TEMPLATE_DECLs.  */
  for (t = OVL_CURRENT (t); t; t = OVL_NEXT (t))
  for (t = OVL_CURRENT (t); t; t = OVL_NEXT (t))
    if (TREE_CODE (t) != TEMPLATE_DECL)
    if (TREE_CODE (t) != TEMPLATE_DECL)
      {
      {
        if (building_stmt_tree ())
        if (building_stmt_tree ())
          add_stmt (build_stmt (input_location, USING_STMT, t));
          add_stmt (build_stmt (input_location, USING_STMT, t));
        else
        else
          (*debug_hooks->imported_module_or_decl) (t, NULL_TREE, context, false);
          (*debug_hooks->imported_module_or_decl) (t, NULL_TREE, context, false);
      }
      }
}
}
 
 
#include "gt-cp-name-lookup.h"
#include "gt-cp-name-lookup.h"
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.