OSDN Git Service

* call.c (joust): Don't warn about "confusing" conversions to the
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index bb916e5..99d8a7f 100644 (file)
@@ -1,6 +1,6 @@
-/* Process declarations and variables for C++ compiler.
-   Copyright (C) 1988, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
-   Hacked by Michael Tiemann (tiemann@cygnus.com)
+/* Process declarations and variables for C compiler.
+   Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
+   Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
 
@@ -29,7 +29,6 @@ Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
-#include <stdio.h>
 #include "tree.h"
 #include "rtl.h"
 #include "flags.h"
@@ -41,6 +40,7 @@ Boston, MA 02111-1307, USA.  */
 #include "defaults.h"
 #include "output.h"
 #include "except.h"
+#include "toplev.h"
 
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
@@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA.  */
 extern tree builtin_return_address_fndecl;
 
 extern struct obstack permanent_obstack;
+extern struct obstack* saveable_obstack;
 
 extern int current_class_depth;
 
@@ -58,6 +59,8 @@ extern int static_labelno;
 extern tree current_namespace;
 extern tree global_namespace;
 
+extern void (*print_error_function) PROTO((char *));
+
 /* Stack of places to restore the search obstack back to.  */
    
 /* Obstack used for remembering local class declarations (like
@@ -132,7 +135,6 @@ static tree grokparms                               PROTO((tree, int));
 static tree lookup_nested_type                 PROTO((tree, tree));
 static char *redeclaration_error_message       PROTO((tree, tree));
 static tree push_overloaded_decl               PROTO((tree, int));
-static void push_overloaded_decl_top_level     PROTO((tree, int));
 
 static struct stack_level *push_decl_level PROTO((struct stack_level *,
                                                  struct obstack *));
@@ -144,7 +146,6 @@ static void resume_binding_level PROTO((struct binding_level *));
 static struct binding_level *make_binding_level PROTO((void));
 static int namespace_bindings_p PROTO((void));
 static void declare_namespace_level PROTO((void));
-static tree get_unique_name PROTO((void));
 static void signal_catch PROTO((int));
 static void storedecls PROTO((tree));
 static void storetags PROTO((tree));
@@ -156,24 +157,29 @@ static tree store_bindings PROTO((tree, tree));
 static tree lookup_tag_reverse PROTO((tree, tree));
 static tree obscure_complex_init PROTO((tree, tree));
 static tree maybe_build_cleanup_1 PROTO((tree, tree));
-static tree lookup_name_real PROTO((tree, int, int));
+static tree lookup_name_real PROTO((tree, int, int, int));
 static void warn_extern_redeclared_static PROTO((tree, tree));
 static void grok_reference_init PROTO((tree, tree, tree));
 static tree grokfndecl PROTO((tree, tree, tree, tree, int,
-                             enum overload_flags,
-                             tree, tree, tree, int, int, int, int, int, int));
-static tree grokvardecl PROTO((tree, tree, RID_BIT_TYPE *, int, int));
+                             enum overload_flags, tree,
+                             tree, tree, int, int, int, int, int, int, tree));
+static tree grokvardecl PROTO((tree, tree, RID_BIT_TYPE *, int, int, tree));
 static tree lookup_tag PROTO((enum tree_code, tree,
                              struct binding_level *, int));
 static void set_identifier_type_value_with_scope
        PROTO((tree, tree, struct binding_level *));
 static void record_builtin_type PROTO((enum rid, char *, tree));
+static void record_unknown_type PROTO((tree, char *));
 static int member_function_or_else PROTO((tree, tree, char *));
 static void bad_specifiers PROTO((tree, char *, int, int, int, int,
                                  int));
-static tree make_implicit_typename PROTO((tree, tree));
+static void lang_print_error_function PROTO((char *));
+
+#if defined (DEBUG_CP_BINDING_LEVELS)
+static void indent PROTO((void));
+#endif
 
-/* a node which has tree code ERROR_MARK, and whose type is itself.
+/* A node which has tree code ERROR_MARK, and whose type is itself.
    All erroneous expressions are replaced with this node.  All functions
    that accept nodes as arguments should avoid generating error messages
    if this node is one of the arguments, since it is undesirable to get
@@ -220,13 +226,24 @@ tree intQI_type_node;
 tree intHI_type_node;
 tree intSI_type_node;
 tree intDI_type_node;
+tree intTI_type_node;
 
 tree unsigned_intQI_type_node;
 tree unsigned_intHI_type_node;
 tree unsigned_intSI_type_node;
 tree unsigned_intDI_type_node;
+tree unsigned_intTI_type_node;
+
+tree java_byte_type_node;
+tree java_short_type_node;
+tree java_int_type_node;
+tree java_long_type_node;
+tree java_float_type_node;
+tree java_double_type_node;
+tree java_char_type_node;
+tree java_boolean_type_node;
 
-/* a VOID_TYPE node, and the same, packaged in a TREE_LIST.  */
+/* A VOID_TYPE node, and the same, packaged in a TREE_LIST.  */
 
 tree void_type_node, void_list_node;
 tree void_zero_node;
@@ -258,11 +275,11 @@ tree wchar_array_type_node;
 /* The bool data type, and constants */
 tree boolean_type_node, boolean_true_node, boolean_false_node;
 
-/* type `int ()' -- used for implicit declaration of functions.  */
+/* Type `int ()' -- used for implicit declaration of functions.  */
 
 tree default_function_type;
 
-/* function types `double (double)' and `double (double, double)', etc.  */
+/* Function types `double (double)' and `double (double, double)', etc.  */
 
 static tree double_ftype_double, double_ftype_double_double;
 static tree int_ftype_int, long_ftype_long;
@@ -296,6 +313,11 @@ tree __ptr_desc_array_type, __attr_dec_array_type, __func_desc_array_type;
 tree __ptmf_desc_array_type, __ptmd_desc_array_type;
 #endif
 
+/* Indicates that there is a type value in some namespace, although
+   that is not necessarily in scope at the moment. */
+
+static tree global_type_node;
+
 tree class_star_type_node;
 tree class_type_node, record_type_node, union_type_node, enum_type_node;
 tree unknown_type_node;
@@ -307,6 +329,10 @@ tree vtbl_type_node;
 
 /* namespace std */
 tree std_node;
+int in_std = 0;
+
+/* Expect only namespace names now. */
+static int only_namespace_names;
 
 /* In a destructor, the point at which all derived class destroying
    has been done, just before any base class destroying will be done.  */
@@ -369,7 +395,7 @@ struct named_label_list
 
 /* A list (chain of TREE_LIST nodes) of named label uses.
    The TREE_PURPOSE field is the list of variables defined
-   the the label's scope defined at the point of use.
+   in the label's scope defined at the point of use.
    The TREE_VALUE field is the LABEL_DECL used.
    The TREE_TYPE field holds `current_binding_level' at the
    point of the label's use.
@@ -584,6 +610,13 @@ struct binding_level
        component_bindings.  */
     tree tags;
 
+    /* A list of USING_DECL nodes. */
+    tree usings;
+
+    /* A list of used namespaces. PURPOSE is the namespace,
+       VALUE the common ancestor with this binding_level's namespace. */
+    tree using_directives;
+
     /* For each level, a list of shadowed outer-level local definitions
        to be restored when this level is popped.
        Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
@@ -742,7 +775,7 @@ pop_binding_level ()
 
   if (global_binding_level)
     {
-      /* cannot pop a level, if there are none left to pop.  */
+      /* Cannot pop a level, if there are none left to pop.  */
       if (current_binding_level == global_binding_level)
        my_friendly_abort (123);
     }
@@ -786,7 +819,7 @@ suspend_binding_level ()
 
   if (global_binding_level)
     {
-      /* cannot suspend a level, if there are none left to suspend.  */
+      /* Cannot suspend a level, if there are none left to suspend.  */
       if (current_binding_level == global_binding_level)
        my_friendly_abort (123);
     }
@@ -818,29 +851,11 @@ static void
 resume_binding_level (b)
      struct binding_level *b;
 {
-  if (class_binding_level)
-    {
-#if 1
-      /* These are here because we cannot deal with shadows yet.  */
-      sorry ("cannot resume a namespace inside class");
-      return;
-#else
-      b->level_chain = class_binding_level;
-      class_binding_level = (struct binding_level *)0;
-#endif
-    }
-  else
-    {
-#if 1
-      /* These are here because we cannot deal with shadows yet.  */
-      if (b->level_chain != current_binding_level)
-       {
-         sorry ("cannot resume a namespace inside a different namespace");
-         return;
-       }
-#endif
-      b->level_chain = current_binding_level;
-    }
+  /* Resuming binding levels is meant only for namespaces,
+     and those cannot nest into classes. */
+  my_friendly_assert(!class_binding_level, 386);
+  /* Also, resuming a non-directly nested namespace is a no-no.  */
+  my_friendly_assert(b->level_chain == current_binding_level, 386);
   current_binding_level = b;
 #if defined(DEBUG_CP_BINDING_LEVELS)
   b->binding_depth = binding_depth;
@@ -872,23 +887,15 @@ global_bindings_p ()
 
 /* Nonzero if we are currently in a toplevel binding level.  This
    means either the global binding level or a namespace in a toplevel
-   binding level.  */
+   binding level.
+   Since there are no non-toplevel namespace levels, this really
+   means any namespace or pseudo-global level.  */
 
 int
 toplevel_bindings_p ()
 {
-  struct binding_level *b = current_binding_level;
-
-  while (1)
-    {
-      if (b == global_binding_level)
-       return 1;
-      if (b->pseudo_global)
-       return 1;
-      if (! b->namespace_p)
-       return 0;
-      b=b->level_chain;
-    }
+  return current_binding_level->namespace_p 
+    || current_binding_level->pseudo_global;
 }
 
 /* Nonzero if this is a namespace scope.  */
@@ -1224,7 +1231,7 @@ poplevel (keep, reverse, functionbody)
        IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
       for (link = current_binding_level->type_shadowed;
           link; link = TREE_CHAIN (link))
-       IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
+       SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));
     }
 
   /* If the level being exited is the top level of a function,
@@ -1328,35 +1335,6 @@ poplevel (keep, reverse, functionbody)
   return block;
 }
 
-/* Resume a binding level for a namespace.  */
-
-void
-resume_level (b)
-     struct binding_level *b;
-{
-  tree decls, link;
-
-  resume_binding_level (b);
-
-  /* Resume the variable caches.  */
-  decls = current_binding_level->names;
-
-  /* Restore the meanings of the local variables of this level.  */
-
-  for (link = decls; link; link = TREE_CHAIN (link))
-    {
-      /* If it doesn't have a name, there is nothing left to do with it.  */
-      if (DECL_NAME (link) == NULL_TREE)
-       continue;
-
-      IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = link;
-
-      /* If this is a TYPE_DECL, push it into the type value slot.  */
-      if (TREE_CODE (link) == TYPE_DECL)
-       SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (link), TREE_TYPE (link));
-    }
-}
-
 /* Delete the node BLOCK from the current binding level.
    This is used for the block inside a stmt expr ({...})
    so that the block can be reinserted where appropriate.  */
@@ -1481,7 +1459,7 @@ poplevel_class (force)
   for (shadowed = level->type_shadowed;
        shadowed;
        shadowed = TREE_CHAIN (shadowed))
-    IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed);
+    SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
 
   GNU_xref_end_scope ((HOST_WIDE_INT) class_binding_level,
                      (HOST_WIDE_INT) class_binding_level->level_chain,
@@ -1491,7 +1469,7 @@ poplevel_class (force)
   if (class_binding_level->parm_flag != 2)
     class_binding_level = (struct binding_level *)0;
 
-  /* Now, pop out of the 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.  */
 #if defined(DEBUG_CP_BINDING_LEVELS)
   is_class_level = 1;
@@ -1660,76 +1638,126 @@ print_binding_stack ()
   print_binding_level (global_binding_level);
 }
 
-/* Return the tree_binding for the name in the given scope
-   If there are no bindings for the name in the scope, make a new
-   bindings node. This bindings list of this node will be empty, though.  */
+/* Namespace binding access routines: The namespace_bindings field of
+   the identifier is polymorphic, with three possible values:
+   NULL_TREE, a list of CPLUS_BINDINGS, or any other tree_node
+   indicating the BINDING_VALUE of global_namespace. */
 
-tree
-binding_for_name (name, scope)
+/* Check whether the a binding for the name to scope is known.
+   Assumes that the bindings of the name are already a list
+   of bindings. Returns the binding found, or NULL_TREE. */
+
+static tree
+find_binding (name, scope)
      tree name;
      tree scope;
 {
-  tree iter;
+  tree iter, prev = NULL_TREE;
+
+  scope = ORIGINAL_NAMESPACE (scope);
+  
   for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter;
        iter = TREE_CHAIN (iter))
     {
       my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374);
       if (BINDING_SCOPE (iter) == scope)
-       return iter;
+       {
+         /* Move binding found to the fron of the list, so
+             subsequent lookups will find it faster. */
+         if (prev)
+           {
+             TREE_CHAIN (prev) = TREE_CHAIN (iter);
+             TREE_CHAIN (iter) = IDENTIFIER_NAMESPACE_BINDINGS (name);
+             IDENTIFIER_NAMESPACE_BINDINGS (name) = iter;
+           }
+         return iter;
+       }
+      prev = iter;
     }
-  /* not found, make a new permanent one */
-  push_obstacks (&permanent_obstack, &permanent_obstack);
-  iter = make_node (CPLUS_BINDING);
-  TREE_CHAIN (iter) = IDENTIFIER_NAMESPACE_BINDINGS (name);
-  IDENTIFIER_NAMESPACE_BINDINGS (name) = iter;
-  BINDING_SCOPE (iter) = scope;
-  BINDING_VALUE (iter) = NULL_TREE;
-  pop_obstacks ();
-  return iter;
+  return NULL_TREE;
 }
 
-extern char * first_global_object_name;
+/* Always returns a binding for name in scope. If the
+   namespace_bindings is not a list, convert it to one first.
+   If no binding is found, make a new one. */
 
-/* Get a unique name for each call to this routine for unnamed namespaces.
-   Mostly copied from get_file_function_name.  */
-
-static tree
-get_unique_name ()
+tree
+binding_for_name (name, scope)
+     tree name;
+     tree scope;
 {
-  static int temp_name_counter = 0;
-  char *buf;
-  register char *p;
+  tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
+  tree result;
 
-  if (first_global_object_name)
-    p = first_global_object_name;
-  else if (main_input_filename)
-    p = main_input_filename;
-  else
-    p = input_filename;
+  scope = ORIGINAL_NAMESPACE (scope);
+  
+  if (b && TREE_CODE (b) != CPLUS_BINDING)
+    {
+      /* Get rid of optimization for global scope. */
+      IDENTIFIER_NAMESPACE_BINDINGS (name) = NULL_TREE;
+      BINDING_VALUE (binding_for_name (name, global_namespace)) = b;
+      b = IDENTIFIER_NAMESPACE_BINDINGS (name);
+    }
+  if (b && (result = find_binding (name, scope)))
+    return result;
+  /* Not found, make a new permanent one. */
+  push_obstacks (&permanent_obstack, &permanent_obstack);
+  result = make_node (CPLUS_BINDING);
+  TREE_CHAIN (result) = b;
+  IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
+  BINDING_SCOPE (result) = scope;
+  BINDING_TYPE (result) = NULL_TREE;
+  BINDING_VALUE (result) = NULL_TREE;
+  pop_obstacks ();
+  return result;
+}
 
-#define UNNAMED_NAMESPACE_FORMAT "__%s_%d"
+/* Return the binding value for name in scope, considering that
+   namespace_binding may or may not be a list of CPLUS_BINDINGS. */
+
+tree
+namespace_binding (name, scope)
+     tree name;
+     tree scope;
+{
+  tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
+  if (b == NULL_TREE)
+    return NULL_TREE;
+  if (scope == NULL_TREE)
+    scope = global_namespace;
+  if (TREE_CODE (b) != CPLUS_BINDING)
+    return (scope == global_namespace) ? b : NULL_TREE;
+  name = find_binding (name,scope);
+  if (name == NULL_TREE)
+    return name;
+  return BINDING_VALUE (name);
+}
 
-  buf = (char *) alloca (sizeof (UNNAMED_NAMESPACE_FORMAT) + strlen (p));
+/* Set the binding value for name in scope. If modifying the binding
+   of global_namespace is attempted, try to optimize it. */
 
-  sprintf (buf, UNNAMED_NAMESPACE_FORMAT, p, temp_name_counter++);
+void
+set_namespace_binding (name, scope, val)
+     tree name;
+     tree scope;
+     tree val;
+{
+  tree b;
 
-  /* Don't need to pull weird characters out of global names.  */
-  if (p != first_global_object_name)
+  if (scope == NULL_TREE)
+    scope = global_namespace;
+  
+  if (scope == global_namespace)
     {
-      for (p = buf+2; *p; p++)
-       if (! ((*p >= '0' && *p <= '9')
-#ifndef NO_DOLLAR_IN_LABEL     /* this for `$'; unlikely, but... -- kr */
-              || *p == '$'
-#endif
-#ifndef NO_DOT_IN_LABEL                /* this for `.'; unlikely, but...  */
-              || *p == '.'
-#endif
-              || (*p >= 'A' && *p <= 'Z')
-              || (*p >= 'a' && *p <= 'z')))
-         *p = '_';
+      b = IDENTIFIER_NAMESPACE_BINDINGS (name);
+      if (b == NULL_TREE || TREE_CODE (b) != CPLUS_BINDING)
+       {
+         IDENTIFIER_NAMESPACE_BINDINGS (name) = val;
+         return;
+       }
     }
-
-  return get_identifier (buf);
+  b = binding_for_name (name, scope);
+  BINDING_VALUE (b) = val;
 }
 
 /* Push into the scope of the NAME namespace.  If NAME is NULL_TREE, then we
@@ -1739,79 +1767,73 @@ void
 push_namespace (name)
      tree name;
 {
-#if 1
   tree d;
   int need_new = 1;
   int implicit_use = 0;
-  int nodecl = 0;
+  int global = 0;
   if (!global_namespace)
     {
-      /* this must be :: */
+      /* This must be ::. */
       my_friendly_assert (name == get_identifier ("::"), 377);
-      nodecl = 1;
+      global = 1;
     }
   else if (!name)
     {
-      name = get_unique_name ();
+      /* The name of anonymous namespace is unique for the translation
+         unit.  */
+      static tree anon_name = NULL_TREE;
+      if (!anon_name)
+        anon_name = get_file_function_name ('N');
+      name = anon_name;
+      d = IDENTIFIER_NAMESPACE_VALUE (name);
+      if (d)
+        /* Reopening anonymous namespace.  */
+        need_new = 0;
       implicit_use = 1;
-    } 
+    }
+  else if (current_namespace == global_namespace
+          && name == DECL_NAME (std_node))
+    {
+      in_std++;
+      return;
+    }
   else
     {
-      /* check whether this is an extended namespace definition */
+      /* Check whether this is an extended namespace definition. */
       d = IDENTIFIER_NAMESPACE_VALUE (name);
       if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
-       need_new = 0;
+        {
+          need_new = 0;
+          if (DECL_NAMESPACE_ALIAS (d))
+            {
+              cp_error ("namespace alias `%D' not allowed here, assuming `%D'",
+                        d, DECL_NAMESPACE_ALIAS (d));
+              d = DECL_NAMESPACE_ALIAS (d);
+            }
+        }
     }
   
   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);
-      if (!nodecl)
-       d = pushdecl (d);
+      /* The global namespace is not pushed, and the global binding
+        level is set elsewhere.  */
+      if (!global)
+       {
+         d = pushdecl (d);
+         pushlevel (0);
+         declare_namespace_level ();
+         NAMESPACE_LEVEL (d) = current_binding_level;
+       }
     }
+  else
+    resume_binding_level (NAMESPACE_LEVEL (d));
+
   if (implicit_use)
     do_using_directive (d);
-  /* enter the name space */
+  /* Enter the name space. */
   current_namespace = d;
-
-#else
-  tree old_id = get_namespace_id ();
-  char *buf;
-  tree d;
-
-  if (! name)
-    {
-      /* Create a truly ugly name! */
-      name = get_unique_name ();
-    }
-
-  d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
-
-  /* Mark them as external, so redeclaration_error_message doesn't think
-     they are duplicates.  */
-
-  DECL_EXTERNAL (d) = 1;
-  d = pushdecl (d);
-
-  if (NAMESPACE_LEVEL (d) == 0)
-    {
-      /* This is new for this compilation unit.  */
-      pushlevel (0);
-      declare_namespace_level ();
-      NAMESPACE_LEVEL (d) = current_binding_level;
-    }
-  else
-    resume_level (NAMESPACE_LEVEL (d));
-
-  /* This code is just is bit old now...  */ 
-  current_namespace = tree_cons (NULL_TREE, name, current_namespace);
-  buf = (char *) alloca (4 + (old_id ? IDENTIFIER_LENGTH (old_id) : 0)
-                        + IDENTIFIER_LENGTH (name));
-  sprintf (buf, "%s%s", old_id ? IDENTIFIER_POINTER (old_id) : "",
-          IDENTIFIER_POINTER (name));
-  TREE_PURPOSE (current_namespace) = get_identifier (buf);
-#endif
 }
 
 /* Pop from the scope of the current namespace.  */
@@ -1819,52 +1841,43 @@ push_namespace (name)
 void
 pop_namespace ()
 {
-#if 1
-  current_namespace = DECL_NAMESPACE (current_namespace);
-#else
-  tree decls, link;
-  current_namespace = TREE_CHAIN (current_namespace);
-
-  /* Just in case we get out of sync.  */
-  if (! namespace_bindings_p ())
-    poplevel (0, 0, 0);
+  if (current_namespace == global_namespace)
+    {
+      my_friendly_assert (in_std>0, 980421);
+      in_std--;
+      return;
+    }
+  current_namespace = CP_DECL_CONTEXT (current_namespace);
+  /* The binding level is not popped, as it might be re-opened later.  */
+  suspend_binding_level ();
+}
 
-  decls = current_binding_level->names;
+/* Concatenate the binding levels of all namespaces. */
 
-  /* Clear out the meanings of the local variables of this level.  */
+void
+cat_namespace_levels()
+{
+  tree current;
+  tree last;
+  struct binding_level *b;
 
-  for (link = decls; link; link = TREE_CHAIN (link))
+  last = NAMESPACE_LEVEL (global_namespace) -> names;
+  /* The nested namespaces appear in the names list of their ancestors. */
+  for (current = last; current; current = TREE_CHAIN (current))
     {
-      if (DECL_NAME (link) != NULL_TREE)
+      if (TREE_CODE (current) != NAMESPACE_DECL)
+       continue;
+      if (!DECL_LANG_SPECIFIC (current))
        {
-         /* If the ident. was used or addressed via a local extern decl,
-            don't forget that fact.  */
-         if (DECL_EXTERNAL (link))
-           {
-             if (TREE_USED (link))
-               TREE_USED (DECL_ASSEMBLER_NAME (link)) = 1;
-             if (TREE_ADDRESSABLE (link))
-               TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
-           }
-         IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE;
+         /* Hmm. std. */
+         my_friendly_assert (current == std_node, 393);
+         continue;
        }
+      b = NAMESPACE_LEVEL (current);
+      while (TREE_CHAIN (last))
+       last = TREE_CHAIN (last);
+      TREE_CHAIN (last) = NAMESPACE_LEVEL (current) -> names;
     }
-
-  /* Restore all name-meanings of the outer levels
-     that were shadowed by this level.  */
-
-  for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
-    IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
-  for (link = current_binding_level->class_shadowed;
-       link; link = TREE_CHAIN (link))
-    IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
-  for (link = current_binding_level->type_shadowed;
-       link; link = TREE_CHAIN (link))
-    IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
-
-  /* suspend a level.  */
-  suspend_binding_level ();
-#endif
 }
 \f
 /* Subroutines for reverting temporarily to top-level for instantiation
@@ -1875,6 +1888,7 @@ pop_namespace ()
 struct saved_scope {
   struct binding_level *old_binding_level;
   tree old_bindings;
+  tree old_namespace;
   struct saved_scope *prev;
   tree class_name, class_type, function_decl;
   struct binding_level *class_bindings;
@@ -1930,7 +1944,7 @@ store_bindings (names, old_bindings)
        {
          my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
          TREE_VEC_ELT (binding, 0) = id;
-         TREE_VEC_ELT (binding, 1) = IDENTIFIER_TYPE_VALUE (id);
+         TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id);
          TREE_VEC_ELT (binding, 2) = IDENTIFIER_LOCAL_VALUE (id);
          TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);
          IDENTIFIER_LOCAL_VALUE (id) = NULL_TREE;
@@ -1966,6 +1980,10 @@ maybe_push_to_top_level (pseudo)
     {
       tree t;
 
+      /* Template IDs are inserted into the global level. If they were
+        inserted into namespace level, finish_file wouldn't find them
+        when doing pending instantiations. Therefore, don't stop at
+        namespace level, but continue until :: .  */
       if (b == global_binding_level || (pseudo && b->pseudo_global))
        break;
 
@@ -1983,6 +2001,7 @@ maybe_push_to_top_level (pseudo)
   s->old_binding_level = current_binding_level;
   current_binding_level = b;
 
+  s->old_namespace = current_namespace;
   s->class_name = current_class_name;
   s->class_type = current_class_type;
   s->function_decl = current_function_decl;
@@ -2009,15 +2028,14 @@ maybe_push_to_top_level (pseudo)
   current_lang_name = lang_name_cplusplus;
   strict_prototype = strict_prototypes_lang_cplusplus;
   named_labels = NULL_TREE;
+  shadowed_labels = NULL_TREE;
   minimal_parse_mode = 0;
   previous_class_type = previous_class_values = NULL_TREE;
   processing_specialization = 0;
   processing_explicit_instantiation = 0;
-  if (!pseudo)
-    {
-      current_template_parms = NULL_TREE;
-      processing_template_decl = 0;
-    }
+  current_template_parms = NULL_TREE;
+  processing_template_decl = 0;
+  current_namespace = global_namespace;
 
   s->prev = current_saved_scope;
   s->old_bindings = old_bindings;
@@ -2056,7 +2074,7 @@ pop_from_top_level ()
       tree id = TREE_VEC_ELT (t, 0);
       if (id)
        {
-         IDENTIFIER_TYPE_VALUE (id) = TREE_VEC_ELT (t, 1);
+         SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1));
          IDENTIFIER_LOCAL_VALUE (id) = TREE_VEC_ELT (t, 2);
          IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
        }
@@ -2064,6 +2082,7 @@ pop_from_top_level ()
       TREE_CHAIN (save) = free_binding_vecs;
       free_binding_vecs = save;
     }
+  current_namespace = s->old_namespace;
   current_class_name = s->class_name;
   current_class_type = s->class_type;
   current_function_decl = s->function_decl;
@@ -2111,12 +2130,21 @@ set_identifier_type_value_with_scope (id, type, b)
      tree type;
      struct binding_level *b;
 {
-  if (b != global_binding_level)
+  if (!b->namespace_p)
     {
-      tree old_type_value = IDENTIFIER_TYPE_VALUE (id);
+      /* Shadow the marker, not the real thing, so that the marker
+        gets restored later. */
+      tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
       b->type_shadowed
        = tree_cons (id, old_type_value, b->type_shadowed);
     }
+  else
+    {
+      tree binding = binding_for_name (id, current_namespace);
+      BINDING_TYPE (binding) = type;
+      /* Store marker instead of real type. */
+      type = global_type_node;
+    }
   SET_IDENTIFIER_TYPE_VALUE (id, type);
 }
 
@@ -2130,6 +2158,26 @@ set_identifier_type_value (id, type)
   set_identifier_type_value_with_scope (id, type, inner_binding_level);
 }
 
+/* Return the type associated with id. */
+
+tree
+identifier_type_value (id)
+     tree id;
+{
+  /* There is no type with that name, anywhere. */
+  if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
+    return NULL_TREE;
+  /* This is not the type marker, but the real thing. */
+  if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
+    return REAL_IDENTIFIER_TYPE_VALUE (id);
+  /* Have to search for it. It must be on the global level, now.
+     Ask lookup_name not to return non-types. */
+  id = lookup_name_real (id, 2, 1, 0);
+  if (id)
+    return TREE_TYPE (id);
+  return NULL_TREE;
+}
+
 /* Pop off extraneous binding levels left over due to syntax errors.
 
    We don't pop past namespaces, as they might be valid.  */
@@ -2153,7 +2201,7 @@ pop_everything ()
 }
 
 /* Push a tag name NAME for struct/class/union/enum type TYPE.
-   Normally put into into the inner-most non-tag-transparent scope,
+   Normally put it into the inner-most non-tag-transparent scope,
    but if GLOBALIZE is true, put it in the inner-most non-class scope.
    The latter is needed for implicit declarations.  */
 
@@ -2196,6 +2244,9 @@ pushtag (name, type, globalize)
        c_decl = TREE_CODE (context) == FUNCTION_DECL
          ? context : TYPE_MAIN_DECL (context);
 
+      if (!context)
+       context = current_namespace;
+
       /* Do C++ gratuitous typedefing.  */
       if (IDENTIFIER_TYPE_VALUE (name) != type)
         {
@@ -2212,6 +2263,8 @@ pushtag (name, type, globalize)
            {
              newdecl = 1;
              d = build_decl (TYPE_DECL, name, type);
+             if (current_lang_name == lang_name_java)
+               TYPE_FOR_JAVA (type) = 1;
              SET_DECL_ARTIFICIAL (d);
              if (! in_class)
                set_identifier_type_value_with_scope (name, type, b);
@@ -2220,15 +2273,64 @@ pushtag (name, type, globalize)
            d = TYPE_MAIN_DECL (d);
 
          TYPE_NAME (type) = d;
-         DECL_CONTEXT (d) = context;
+         DECL_CONTEXT (d) = FROB_CONTEXT (context);
 
-         if (! globalize && processing_template_decl
-             && IS_AGGR_TYPE (type))
-           {
-             d = push_template_decl (d);
-             if (b->pseudo_global && b->level_chain->parm_flag == 2)
-               pushdecl_with_scope (CLASSTYPE_TI_TEMPLATE (type),
-                                    b->level_chain);
+         if (processing_template_parmlist)
+           /* You can't declare a new template type in a template
+              parameter list.  But, you can declare a non-template
+              type:
+
+                template <class A*> struct S;
+
+              is a forward-declaration of `A'.  */
+           ;
+         else if (IS_AGGR_TYPE (type)
+             && (/* If !GLOBALIZE then we are looking at a
+                    definition.  It may not be a primary template.
+                    (For example, in:
+                 
+                      template <class T>
+                      struct S1 { class S2 {}; }
+                 
+                    we have to push_template_decl for S2.)  */
+                 (processing_template_decl && !globalize)
+                 /* If we are declaring a friend template class, we
+                    will have GLOBALIZE set, since something like:
+
+                      template <class T>
+                      struct S1 {
+                        template <class U>
+                        friend class S2; 
+                      };
+
+                    declares S2 to be at global scope.  */
+                 || (processing_template_decl > 
+                     template_class_depth (current_class_type))))
+           {
+             d = push_template_decl_real (d, globalize);
+             /* If the current binding level is the binding level for
+                the template parameters (see the comment in
+                begin_template_parm_list) and the enclosing level is
+                a class scope, and we're not looking at a friend,
+                push the declaration of the member class into the
+                class scope.  In the friend case, push_template_decl
+                will already have put the friend into global scope,
+                if appropriate.  */ 
+             if (!globalize && b->pseudo_global &&
+                 b->level_chain->parm_flag == 2)
+               {
+                 pushdecl_with_scope (CLASSTYPE_TI_TEMPLATE (type),
+                                      b->level_chain);
+                 /* Put this tag on the list of tags for the class,
+                    since that won't happen below because B is not
+                    the class binding level, but is instead the
+                    pseudo-global level.  */
+                 b->level_chain->tags = 
+                   saveable_tree_cons (name, type, b->level_chain->tags);
+                 TREE_NONLOCAL_FLAG (type) = 1;
+                 if (TYPE_SIZE (current_class_type) == NULL_TREE)
+                   CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags;
+               }
            }
 
          if (b->parm_flag == 2)
@@ -2483,29 +2585,23 @@ duplicate_decls (newdecl, olddecl)
   extern struct obstack permanent_obstack;
   unsigned olddecl_uid = DECL_UID (olddecl);
   int olddecl_friend = 0, types_match = 0;
-  int new_defines_function;
+  int new_defines_function = 0;
 
   if (newdecl == olddecl)
     return 1;
 
-  if (TREE_CODE_CLASS (TREE_CODE (olddecl)) == 'd')
-    DECL_MACHINE_ATTRIBUTES (newdecl)
-      = merge_machine_decl_attributes (olddecl, newdecl);
-
   types_match = decls_match (newdecl, olddecl);
 
-  if (TREE_CODE (olddecl) != TREE_LIST)
-    olddecl_friend = DECL_LANG_SPECIFIC (olddecl) && DECL_FRIEND_P (olddecl);
-
   /* If either the type of the new decl or the type of the old decl is an
      error_mark_node, then that implies that we have already issued an
      error (earlier) for some bogus type specification, and in that case,
      it is rather pointless to harass the user with yet more error message
-     about the same declaration, so well just pretent the types match here.  */
+     about the same declaration, so just pretend the types match here.  */
   if (TREE_TYPE (newdecl) == error_mark_node
       || TREE_TYPE (olddecl) == error_mark_node)
     types_match = 1;
-
+  /* Check for redeclaration and other discrepancies. */
   if (TREE_CODE (olddecl) == FUNCTION_DECL
       && DECL_ARTIFICIAL (olddecl)
       && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl)))
@@ -2652,7 +2748,7 @@ duplicate_decls (newdecl, olddecl)
          cp_error (errmsg, newdecl);
          if (DECL_NAME (olddecl) != NULL_TREE)
            cp_error_at ((DECL_INITIAL (olddecl)
-                         && current_binding_level == global_binding_level)
+                         && namespace_bindings_p ())
                         ? "`%#D' previously defined here"
                         : "`%#D' previously declared here", olddecl);
        }
@@ -2752,8 +2848,6 @@ duplicate_decls (newdecl, olddecl)
        DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
       if (DECL_CLASS_CONTEXT (olddecl))
        DECL_CLASS_CONTEXT (newdecl) = DECL_CLASS_CONTEXT (olddecl);
-      if (DECL_CHAIN (newdecl) == NULL_TREE)
-       DECL_CHAIN (newdecl) = DECL_CHAIN (olddecl);
       if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)0)
        DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl);
       DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl);
@@ -2761,6 +2855,21 @@ duplicate_decls (newdecl, olddecl)
       DECL_ABSTRACT_VIRTUAL_P (newdecl) |= DECL_ABSTRACT_VIRTUAL_P (olddecl);
       DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
       DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
+      new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
+      
+      /* Optionally warn about more than one declaration for the same
+         name, but don't warn about a function declaration followed by a
+         definition.  */
+      if (warn_redundant_decls && ! DECL_ARTIFICIAL (olddecl)
+         && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)
+         /* Don't warn about extern decl followed by definition. */
+         && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl))
+         /* Don't warn about friends, let add_friend take care of it. */
+         && ! DECL_FRIEND_P (newdecl))
+       {
+         cp_warning ("redundant redeclaration of `%D' in same scope", newdecl);
+         cp_warning_at ("previous declaration of `%D'", olddecl);
+       }
     }
 
   /* Deal with C++: must preserve virtual function table size.  */
@@ -2778,24 +2887,10 @@ duplicate_decls (newdecl, olddecl)
        }
     }
 
-  /* Special handling ensues if new decl is a function definition.  */
-  new_defines_function = (TREE_CODE (newdecl) == FUNCTION_DECL
-                         && DECL_INITIAL (newdecl) != NULL_TREE);
-
-  /* Optionally warn about more than one declaration for the same name,
-     but don't warn about a function declaration followed by a definition.  */
-  if (warn_redundant_decls
-      && ! DECL_ARTIFICIAL (olddecl)
-      && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)
-      /* Don't warn about extern decl followed by (tentative) definition.  */
-      && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)))
-    {
-      cp_warning ("redundant redeclaration of `%D' in same scope", newdecl);
-      cp_warning_at ("previous declaration of `%D'", olddecl);
-    }
-
   /* Copy all the DECL_... slots specified in the new decl
      except for any that we copy here from the old type.  */
+  DECL_MACHINE_ATTRIBUTES (newdecl) 
+    = merge_machine_decl_attributes (olddecl, newdecl);
 
   if (TREE_CODE (newdecl) == TEMPLATE_DECL)
     {
@@ -2808,9 +2903,12 @@ duplicate_decls (newdecl, olddecl)
          DECL_TEMPLATE_PARMS (olddecl) = DECL_TEMPLATE_PARMS (newdecl);
          DECL_TEMPLATE_INFO (olddecl) = DECL_TEMPLATE_INFO (newdecl);
        }
+      DECL_TEMPLATE_SPECIALIZATIONS (newdecl)
+       = DECL_TEMPLATE_SPECIALIZATIONS (olddecl);
       return 1;
     }
-
+    
   if (types_match)
     {
       /* Automatically handles default parameters.  */
@@ -2855,7 +2953,7 @@ duplicate_decls (newdecl, olddecl)
       TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype;
 
       /* Lay the type out, unless already done.  */
-      if (oldtype != TREE_TYPE (newdecl)
+      if (newtype != CANONICAL_TYPE_VARIANT (oldtype)
          && TREE_TYPE (newdecl) != error_mark_node
          && !(processing_template_decl && uses_template_parms (newdecl)))
        layout_type (TREE_TYPE (newdecl));
@@ -2921,12 +3019,23 @@ duplicate_decls (newdecl, olddecl)
   TREE_STATIC (olddecl) = TREE_STATIC (newdecl) |= TREE_STATIC (olddecl);
   if (! DECL_EXTERNAL (olddecl))
     DECL_EXTERNAL (newdecl) = 0;
-
-  if (DECL_LANG_SPECIFIC (newdecl))
+  
+  if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl))
     {
       DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
       DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
       DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
+      /* Don't really know how much of the language-specific
+        values we should copy from old to new.  */
+      DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
+      DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
+      DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
+      if (DECL_TEMPLATE_INFO (newdecl) == NULL_TREE)
+       {
+         DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
+         DECL_USE_TEMPLATE (newdecl) = DECL_USE_TEMPLATE (olddecl);
+       }
+      olddecl_friend = DECL_FRIEND_P (olddecl);
     }
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
@@ -3011,34 +3120,12 @@ duplicate_decls (newdecl, olddecl)
       NAMESPACE_LEVEL (newdecl) = NAMESPACE_LEVEL (olddecl);
     }
 
-  if (TREE_CODE (newdecl) == TEMPLATE_DECL)
-    {
-      DECL_TEMPLATE_SPECIALIZATIONS (newdecl)
-       = DECL_TEMPLATE_SPECIALIZATIONS (olddecl);
-      if (DECL_CHAIN (newdecl) == NULL_TREE)
-       DECL_CHAIN (newdecl) = DECL_CHAIN (olddecl);
-    }
-
   /* Now preserve various other info from the definition.  */
   TREE_ADDRESSABLE (newdecl) = TREE_ADDRESSABLE (olddecl);
   TREE_ASM_WRITTEN (newdecl) = TREE_ASM_WRITTEN (olddecl);
   DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
   DECL_ASSEMBLER_NAME (newdecl) = DECL_ASSEMBLER_NAME (olddecl);
 
-  /* Don't really know how much of the language-specific
-     values we should copy from old to new.  */
-  if (DECL_LANG_SPECIFIC (olddecl))
-    {
-      DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
-      DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
-      DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
-      if (DECL_TEMPLATE_INFO (newdecl) == NULL_TREE)
-       {
-         DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
-         DECL_USE_TEMPLATE (newdecl) = DECL_USE_TEMPLATE (olddecl);
-       }
-    }
-
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
       int function_size;
@@ -3088,9 +3175,12 @@ duplicate_decls (newdecl, olddecl)
              TREE_VALUE (decls) = olddecl;
        }
 
-      if ((char *)newdecl + ROUND (function_size)
-         + ROUND (sizeof (struct lang_decl))
-         == obstack_next_free (&permanent_obstack))
+      if (((char *)newdecl + ROUND (function_size) == (char *)nl
+          && ((char *)newdecl + ROUND (function_size)
+              + ROUND (sizeof (struct lang_decl))
+              == obstack_next_free (&permanent_obstack)))
+         || ((char *)newdecl + ROUND (function_size)
+             == obstack_next_free (&permanent_obstack)))
        {
          DECL_MAIN_VARIANT (newdecl) = olddecl;
          DECL_LANG_SPECIFIC (olddecl) = ol;
@@ -3153,14 +3243,15 @@ pushdecl (x)
   register tree name = DECL_ASSEMBLER_NAME (x);
   register struct binding_level *b = current_binding_level;
 
-  if (x != current_function_decl
+  if (current_function_decl && x != current_function_decl
+      /* A local declaration for a function doesn't constitute nesting.  */
+      && (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x))
       /* Don't change DECL_CONTEXT of virtual methods.  */
       && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x))
       && ! DECL_CONTEXT (x))
     DECL_CONTEXT (x) = current_function_decl;
-  /* A local declaration for a function doesn't constitute nesting.  */
-  if (TREE_CODE (x) == FUNCTION_DECL && DECL_INITIAL (x) == 0)
-    DECL_CONTEXT (x) = 0;
+  if (!DECL_CONTEXT (x))
+    DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace);
 
   /* Type are looked up using the DECL_NAME, as that is what the rest of the
      compiler wants to use.  */
@@ -3179,7 +3270,11 @@ pushdecl (x)
       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
        name = TREE_OPERAND (name, 0);
       
-      t = lookup_name_current_level (name);
+      /* Namespace-scoped variables are not found in the current level. */
+      if (TREE_CODE (x) == VAR_DECL && DECL_NAMESPACE_SCOPE_P (x))
+       t = namespace_binding (name, DECL_CONTEXT (x));
+      else
+       t = lookup_name_current_level (name);
       if (t == error_mark_node)
        {
          /* error_mark_node is 0 for a while during initialization!  */
@@ -3207,7 +3302,7 @@ pushdecl (x)
          else if (((TREE_CODE (x) == FUNCTION_DECL && DECL_LANGUAGE (x) == lang_c)
                    || DECL_FUNCTION_TEMPLATE_P (x))
                   && is_overloaded_fn (t))
-           /* don't do anything just yet */;
+           /* Don't do anything just yet. */;
          else if (t == wchar_decl_node)
            {
              if (pedantic && ! DECL_IN_SYSTEM_HEADER (x))
@@ -3277,6 +3372,20 @@ pushdecl (x)
 
              return t;
            }
+         else if (DECL_MAIN_P (x))
+           {
+             /* A redeclaration of main, but not a duplicate of the
+                previous one. 
+
+                [basic.start.main]
+
+                This function shall not be overloaded.  */
+             cp_error_at ("invalid redeclaration of `%D'", t);
+             cp_error ("as `%D'", x);
+             /* We don't try to push this declaration since that
+                causes a crash.  */
+             return x;
+           }
        }
 
       if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_FUNCTION_MEMBER_P (x))
@@ -3285,25 +3394,32 @@ pushdecl (x)
          if (t != x || DECL_LANGUAGE (x) == lang_c)
            return t;
        }
-      else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_CONTEXT (x) == NULL_TREE)
+      else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
        return push_overloaded_decl (x, 0);
 
-      /* If declaring a type as a typedef, and the type has no known
-        typedef name, install this TYPE_DECL as its typedef name.  */
+      /* 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
+        name.  See the extensive comment in ../c-decl.c (pushdecl). */
       if (TREE_CODE (x) == TYPE_DECL)
        {
          tree type = TREE_TYPE (x);
-         tree name = (type != error_mark_node) ? TYPE_NAME (type) : x;
+          if (DECL_SOURCE_LINE (x) == 0)
+            {
+             if (TYPE_NAME (type) == 0)
+               TYPE_NAME (type) = x;
+            }
+          else if (type != error_mark_node && TYPE_NAME (type) != x)
+            {
+             push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
+
+             DECL_ORIGINAL_TYPE (x) = type;
+              type = build_type_copy (type);
+             TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
+              TYPE_NAME (type) = x;
+              TREE_TYPE (x) = type;
 
-         if (name == NULL_TREE || TREE_CODE (name) != TYPE_DECL)
-           {
-             /* If these are different names, and we're at the global
-                binding level, make two equivalent definitions.  */
-              name = x;
-              if (global_bindings_p ())
-                TYPE_NAME (type) = x;
-           }
-         my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 140);
+             pop_obstacks ();
+            }
 
          if (type != error_mark_node
              && TYPE_NAME (type)
@@ -3341,7 +3457,7 @@ pushdecl (x)
 
       /* This name is new in its binding level.
         Install the new declaration and return it.  */
-      if (b == global_binding_level)
+      if (namespace_bindings_p ())
        {
          /* Install a global value.  */
          tree bindings = binding_for_name (name, current_namespace);
@@ -3546,15 +3662,17 @@ pushdecl_with_scope (x, level)
   return x;
 }
 
-/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL,
+/* Like pushdecl, only it places X in the current namespace,
    if appropriate.  */
 
 tree
-pushdecl_top_level (x)
+pushdecl_namespace_level (x)
      tree x;
 {
   register struct binding_level *b = inner_binding_level;
-  register tree t = pushdecl_with_scope (x, global_binding_level);
+  register tree t;
+
+  t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace));
 
   /* Now, the type_shadowed stack may screw us.  Munge it so it does
      what we want.  */
@@ -3590,19 +3708,18 @@ pushdecl_top_level (x)
   return t;
 }
 
-/* Like push_overloaded_decl, only it places X in GLOBAL_BINDING_LEVEL,
+/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL,
    if appropriate.  */
 
-static void
-push_overloaded_decl_top_level (x, forget)
+tree
+pushdecl_top_level (x)
      tree x;
-     int forget;
 {
-  struct binding_level *b = current_binding_level;
-
-  current_binding_level = global_binding_level;
-  push_overloaded_decl (x, forget);
-  current_binding_level = b;
+  tree cur_namespace = current_namespace;
+  current_namespace = global_namespace;
+  x = pushdecl_namespace_level (x);
+  current_namespace = cur_namespace;
+  return x;
 }
 
 /* Make the declaration of X appear in CLASS scope.  */
@@ -3619,21 +3736,24 @@ pushdecl_class_level (x)
     {
       if (TYPE_BEING_DEFINED (current_class_type))
        {
-         /* Check for inconsistent use of this name in the class body.
+         /* A name N used in a class S shall refer to the same declaration
+            in its context and when re-evaluated in the completed scope of S.
+
             Types, enums, and static vars are checked here; other
             members are checked in finish_struct.  */
          tree icv = IDENTIFIER_CLASS_VALUE (name);
 
          if (icv && icv != x
+             && flag_optional_diags
              /* Don't complain about inherited names.  */
              && id_in_current_class (name)
              /* Or shadowed tags.  */
-             && !(TREE_CODE (icv) == TYPE_DECL
+             && !(DECL_DECLARES_TYPE_P (icv)
                   && DECL_CONTEXT (icv) == current_class_type))
            {
-             cp_error ("declaration of identifier `%D' as `%#D'", name, x);
-             cp_error_at ("conflicts with previous use in class as `%#D'",
-                          icv);
+             cp_pedwarn ("declaration of identifier `%D' as `%#D'", name, x);
+             cp_pedwarn_at ("conflicts with previous use in class as `%#D'",
+                            icv);
            }
        }
 
@@ -3695,23 +3815,49 @@ push_class_level_binding (name, x)
   obstack_ptr_grow (&decl_obstack, x);
 }
 
-/* Tell caller how to interpret a TREE_LIST which contains
-   chains of FUNCTION_DECLS.  */
+/* Insert another USING_DECL into the current binding level,
+   returning this declaration. If this is a redeclaration,
+   do nothing and return NULL_TREE.  */
 
-int
-overloaded_globals_p (list)
-     tree list;
+tree
+push_using_decl (scope, name)
+     tree scope;
+     tree name;
 {
-  my_friendly_assert (TREE_CODE (list) == TREE_LIST, 142);
+  tree decl;
+  
+  my_friendly_assert (TREE_CODE (scope) == NAMESPACE_DECL, 383);
+  my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 384);
+  for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
+    if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name)
+      break;
+  if (decl)
+    return NULL_TREE;
+  decl = build_lang_decl (USING_DECL, name, void_type_node);
+  DECL_INITIAL (decl) = scope;
+  TREE_CHAIN (decl) = current_binding_level->usings;
+  current_binding_level->usings = decl;
+  return decl;
+}
 
-  /* Don't commit caller to seeing them as globals.  */
-  if (TREE_NONLOCAL_FLAG (list))
-    return -1;
-  /* Do commit caller to not seeing them as globals.  */
-  if (TREE_CODE (TREE_VALUE (list)) == TREE_LIST)
-    return 0;
-  /* Do commit caller to seeing them as globals.  */
-  return 1;
+/* Add namespace to using_directives. Return NULL_TREE if nothing was
+   changed (i.e. there was already a directive), or the fresh
+   TREE_LIST otherwise.  */
+
+tree
+push_using_directive (used, ancestor)
+     tree used;
+     tree ancestor;
+{
+  tree ud = current_binding_level->using_directives;
+  
+  /* Check if we already have this. */
+  if (purpose_member (used, ud) != NULL_TREE)
+    return NULL_TREE;
+  ud = perm_tree_cons (used, ancestor, ud);
+  current_binding_level->using_directives = ud;
+  return ud;
 }
 
 /* DECL is a FUNCTION_DECL which may have other definitions already in
@@ -3734,11 +3880,11 @@ push_overloaded_decl (decl, forgettable)
 {
   tree orig_name = DECL_NAME (decl);
   tree old;
-  int doing_global = (global_bindings_p () || ! forgettable);
+  int doing_global = (namespace_bindings_p () || ! forgettable);
 
   if (doing_global)
     {
-      old =  IDENTIFIER_NAMESPACE_VALUE (orig_name);
+      old = namespace_binding (orig_name, DECL_CONTEXT (decl));
       if (old && TREE_CODE (old) == FUNCTION_DECL
          && DECL_ARTIFICIAL (old)
          && (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old)))
@@ -3775,9 +3921,10 @@ push_overloaded_decl (decl, forgettable)
         {
           tree tmp;
          
-         for (tmp = get_first_fn (old); tmp; tmp = DECL_CHAIN (tmp))
-           if (decl == tmp || duplicate_decls (decl, tmp))
-             return tmp;
+         for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
+           if (decl == OVL_CURRENT (tmp) 
+               || duplicate_decls (decl, OVL_CURRENT (tmp)))
+             return OVL_CURRENT (tmp);
        }
       else
        {
@@ -3789,19 +3936,16 @@ push_overloaded_decl (decl, forgettable)
 
   if (old || TREE_CODE (decl) == TEMPLATE_DECL)
     {
-      if (old && is_overloaded_fn (old))
-       DECL_CHAIN (decl) = get_first_fn (old);
-      else
-       DECL_CHAIN (decl) = NULL_TREE;
-      old = tree_cons (orig_name, decl, NULL_TREE);
-      TREE_TYPE (old) = unknown_type_node;
+      if (old && TREE_CODE (old) != OVERLOAD)
+       old = ovl_cons (old, NULL_TREE);
+      old = ovl_cons (decl, old);
     }
   else
     /* orig_name is not ambiguous.  */
     old = decl;
 
   if (doing_global)
-    IDENTIFIER_NAMESPACE_VALUE (orig_name) = old;
+    set_namespace_binding (orig_name, DECL_CONTEXT (decl), old);
   else
     IDENTIFIER_LOCAL_VALUE (orig_name) = old;
 
@@ -3881,10 +4025,16 @@ redeclaration_error_message (newdecl, olddecl)
       if (DECL_LANG_SPECIFIC (olddecl) && DECL_ABSTRACT_VIRTUAL_P (olddecl))
        return 0;
 
+      /* If both functions come from different namespaces, this is not
+        a redeclaration - this is a conflict with a used function. */
+      if (DECL_NAMESPACE_SCOPE_P (olddecl)
+         && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl))
+       return "`%D' conflicts with used function";
+
       /* We'll complain about linkage mismatches in
          warn_extern_redeclared_static.  */
 
-      /* defining the same name twice is no good.  */
+      /* Defining the same name twice is no good.  */
       if (DECL_INITIAL (olddecl) != NULL_TREE
          && DECL_INITIAL (newdecl) != NULL_TREE)
        {
@@ -4012,7 +4162,6 @@ shadow_label (name)
     {
       shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels);
       SET_IDENTIFIER_LABEL_VALUE (name, NULL_TREE);
-      SET_IDENTIFIER_LABEL_VALUE (decl, NULL_TREE);
     }
 
   return lookup_label (name);
@@ -4281,6 +4430,27 @@ lookup_tag (form, name, binding_level, thislevel_only)
            if (TYPE_IDENTIFIER (TREE_VALUE (tail)) == name)
              return TREE_VALUE (tail);
          }
+      else if (level->namespace_p)
+       /* Do namespace lookup. */
+       /* XXX: is this a real lookup, considering using-directives etc. ??? */
+       for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
+         {
+           tree old = BINDING_TYPE (binding_for_name (name, tail));
+           /* If it has an original type, it is a typedef, and we
+              should not return it.  */
+           if (old && DECL_ORIGINAL_TYPE (TYPE_NAME (old)))
+             old = NULL_TREE;
+           if (old && TREE_CODE (old) != form
+               && !(form != ENUMERAL_TYPE && TREE_CODE (old) == TEMPLATE_DECL))
+             {
+               cp_error ("`%#D' redeclared as %C", old, form);
+               return NULL_TREE;
+             }
+           if (old)
+             return old;
+           if (thislevel_only || tail == global_namespace)
+             return NULL_TREE;
+         }
       else
        for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
          {
@@ -4304,15 +4474,16 @@ lookup_tag (form, name, binding_level, thislevel_only)
        {
          if (level->pseudo_global)
            {
-             /* XXX MvL */
-             tree t = IDENTIFIER_NAMESPACE_VALUE (name);
-             if (t && TREE_CODE (t) == TEMPLATE_DECL
-                 && TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
+             tree t = IDENTIFIER_CLASS_VALUE (name);
+             if (t && DECL_CLASS_TEMPLATE_P (t))
+               return TREE_TYPE (t);
+             t = IDENTIFIER_NAMESPACE_VALUE (name);
+             if (t && DECL_CLASS_TEMPLATE_P (t))
                return TREE_TYPE (t);
            }
          return NULL_TREE;
        }
-      if (current_class_type && level->level_chain == global_binding_level)
+      if (current_class_type && level->level_chain->namespace_p)
        {
          /* Try looking in this class's tags before heading into
             global binding level.  */
@@ -4456,38 +4627,20 @@ tree
 lookup_namespace_name (namespace, name)
      tree namespace, name;
 {
-#if 1
+  struct tree_binding _b;
   tree val;
+
   my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370);
   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
   
-  val = qualified_lookup_using_namespace (name, namespace);
-  if (val)
-    return val;
+  val = binding_init (&_b);
+  if (!qualified_lookup_using_namespace (name, namespace, val))
+    return error_mark_node;
+
+  if (BINDING_VALUE (val))
+    return BINDING_VALUE (val);
   cp_error ("`%D' undeclared in namespace `%D'", name, namespace);
   return error_mark_node;
-#else
-  struct binding_level *b = (struct binding_level *)NAMESPACE_LEVEL (namespace);
-  tree x = NULL_TREE;
-#if 1
-  /* This searches just one level.  */
-  if (b)
-    {
-      for (x = b->names; x; x = TREE_CHAIN (x))
-       if (DECL_NAME (x) == name || DECL_ASSEMBLER_NAME (x) == name)
-         break;
-    }
-#else
-  /* This searches all levels.  */
-  for (; b && !x; b = b->level_chain)
-    {
-      for (x = b->names; x; x = TREE_CHAIN (x))
-       if (DECL_NAME (x) == name || DECL_ASSEMBLER_NAME (x) == name)
-         break;
-    }
-#endif
-  return x;
-#endif
 }
 
 tree
@@ -4514,7 +4667,7 @@ make_typename_type (context, name)
     my_friendly_abort (2000);
 
   if (! uses_template_parms (context)
-      || context == current_class_type)
+      || currently_open_class (context))
     {
       if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR)
        {
@@ -4559,22 +4712,108 @@ make_typename_type (context, name)
   if (processing_template_decl)
     pop_obstacks ();
 
-  TYPE_CONTEXT (t) = context;
+  TYPE_CONTEXT (t) = FROB_CONTEXT (context);
   TYPE_NAME (TREE_TYPE (d)) = d;
   TYPE_STUB_DECL (TREE_TYPE (d)) = d;
-  DECL_CONTEXT (d) = context;
+  DECL_CONTEXT (d) = FROB_CONTEXT (context);
   CLASSTYPE_GOT_SEMICOLON (t) = 1;
 
   return t;
 }
 
+/* Select the right _DECL from multiple choices. */
+
+static tree
+select_decl (binding, prefer_type, namespaces_only)
+     tree binding;
+     int prefer_type, namespaces_only;
+{
+  tree val;
+  val = BINDING_VALUE (binding);
+  if (namespaces_only)
+    {
+      /* We are not interested in types. */
+      if (val && TREE_CODE (val) == NAMESPACE_DECL)
+        return val;
+      return NULL_TREE;
+    }
+  
+  /* If we could have a type and
+     we have nothing or we need a type and have none.  */
+  if (BINDING_TYPE (binding)
+      && (!val || (prefer_type && TREE_CODE (val) != TYPE_DECL)))
+    val = TYPE_STUB_DECL (BINDING_TYPE (binding));
+  /* Don't return non-types if we really prefer types. */
+  else if (val && prefer_type > 1  && TREE_CODE (val) != TYPE_DECL
+          && (!looking_for_template || TREE_CODE (val) != TEMPLATE_DECL))
+    val = NULL_TREE;
+  return val;
+}
+
+/* Unscoped lookup of a global, iterate over namespaces, considering
+   using namespace statements. */
+
+static tree
+unqualified_namespace_lookup (name, prefer_type, namespaces_only)
+     tree name;
+     int prefer_type;
+     int namespaces_only;
+{
+  struct tree_binding _binding;
+  tree b = binding_init (&_binding);
+  tree initial = current_decl_namespace();
+  tree scope = initial;
+  tree siter;
+  struct binding_level *level;
+  tree val = NULL_TREE;
+
+  while (!val)
+    {
+      val = binding_for_name (name, scope);
+
+      /* Initialize binding for this context. */
+      BINDING_VALUE (b) = BINDING_VALUE (val);
+      BINDING_TYPE (b) = BINDING_TYPE (val);
+
+      /* Add all _DECLs seen through local using-directives. */
+      for (level = current_binding_level; 
+          !level->namespace_p;
+          level = level->level_chain)
+       if (!lookup_using_namespace (name, b, level->using_directives, scope))
+         /* Give up because of error. */
+         return NULL_TREE;
+
+      /* Add all _DECLs seen through global using-directives. */
+      /* XXX local and global using lists should work equally. */
+      siter = initial;
+      while (1)
+       {
+         if (!lookup_using_namespace (name, b, DECL_NAMESPACE_USING (siter), 
+                                      scope))
+           /* Give up because of error. */
+           return NULL_TREE;
+         if (siter == scope) break;
+         siter = CP_DECL_CONTEXT (siter);
+       }
+
+      val = select_decl (b, prefer_type, namespaces_only);
+      if (scope == global_namespace)
+       break;
+      scope = DECL_CONTEXT (scope);
+      if (scope == NULL_TREE)
+       scope = global_namespace;
+    }
+  return val;
+}
+
 /* Look up NAME in the current binding level and its superiors in the
    namespace of variables, functions and typedefs.  Return a ..._DECL
    node of some kind representing its definition if there is only one
    such declaration, or return a TREE_LIST with all the overloaded
    definitions if there are many, or return 0 if it is undefined.
 
-   If PREFER_TYPE is > 0, we prefer TYPE_DECLs.
+   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 -2, we're being called from yylex(). (UGLY)
    Otherwise we prefer non-TYPE_DECLs.  
 
@@ -4582,15 +4821,19 @@ make_typename_type (context, name)
    using IDENTIFIER_CLASS_VALUE.  */
 
 static tree
-lookup_name_real (name, prefer_type, nonclass)
+lookup_name_real (name, prefer_type, nonclass, namespaces_only)
      tree name;
-     int prefer_type, nonclass;
+     int prefer_type, nonclass, namespaces_only;
 {
   register tree val;
   int yylex = 0;
   tree from_obj = NULL_TREE;
   tree locval, classval;
 
+  /* Hack: copy flag set by parser, if set. */
+  if (only_namespace_names)
+    namespaces_only = 1;
+  
   if (prefer_type == -2)
     {
       extern int looking_for_typename;
@@ -4615,13 +4858,18 @@ lookup_name_real (name, prefer_type, nonclass)
          if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type))
            type = TREE_TYPE (type);
 
-         type = complete_type (type);
+         if (TYPE_P (type))
+           type = complete_type (type);
 
-         if (type == void_type_node)
-           val = IDENTIFIER_GLOBAL_VALUE (name);
-         else if (TREE_CODE (type) == NAMESPACE_DECL)
+         if (TREE_CODE (type) == VOID_TYPE)
+           type = global_namespace;
+         if (TREE_CODE (type) == NAMESPACE_DECL)
            {
-             val = NAMESPACE_BINDING (name, type);
+             struct tree_binding b;
+             val = binding_init (&b);
+             if (!qualified_lookup_using_namespace (name, type, val))
+               return NULL_TREE;
+             val = select_decl (val, prefer_type, namespaces_only);
            }
          else if (! IS_AGGR_TYPE (type)
                   || TREE_CODE (type) == TEMPLATE_TYPE_PARM
@@ -4652,7 +4900,7 @@ lookup_name_real (name, prefer_type, nonclass)
          else if (type == current_class_type)
            val = IDENTIFIER_CLASS_VALUE (name);
          else
-           val = lookup_field (type, name, 0, prefer_type);
+           val = lookup_member (type, name, 0, prefer_type);
        }
       else
        val = NULL_TREE;
@@ -4665,8 +4913,11 @@ lookup_name_real (name, prefer_type, nonclass)
 
   locval = classval = NULL_TREE;
 
-  if (current_binding_level != global_binding_level
-      && IDENTIFIER_LOCAL_VALUE (name))
+  if (!namespaces_only && !current_binding_level->namespace_p
+      && IDENTIFIER_LOCAL_VALUE (name)
+      /* Kludge to avoid infinite recursion with identifier_type_value.  */
+      && (prefer_type <= 0
+          || TREE_CODE (IDENTIFIER_LOCAL_VALUE (name)) == TYPE_DECL))
     locval = IDENTIFIER_LOCAL_VALUE (name);
 
   /* In C++ class fields are between local and global scope,
@@ -4680,20 +4931,21 @@ lookup_name_real (name, prefer_type, nonclass)
           TYPE_DECLs.  */
        classval = lookup_field (current_class_type, name, 0, 1);
 
-      /* yylex() calls this with -2, since we should never start digging for
-        the nested name at the point where we haven't even, for example,
-        created the COMPONENT_REF or anything like that.  */
-      if (classval == NULL_TREE)
-       classval = lookup_nested_field (name, ! yylex);
-
       /* Add implicit 'typename' to types from template bases.  lookup_field
-         will do this for us.  */
+         will do this for us.  If classval is actually from an enclosing
+         scope, lookup_nested_field will get it for us.  */
       if (processing_template_decl
          && classval && TREE_CODE (classval) == TYPE_DECL
-         && DECL_CONTEXT (classval) != current_class_type
+         && ! currently_open_class (DECL_CONTEXT (classval))
          && uses_template_parms (current_class_type)
          && ! DECL_ARTIFICIAL (classval))
        classval = lookup_field (current_class_type, name, 0, 1);
+
+      /* yylex() calls this with -2, since we should never start digging for
+        the nested name at the point where we haven't even, for example,
+        created the COMPONENT_REF or anything like that.  */
+      if (classval == NULL_TREE)
+       classval = lookup_nested_field (name, ! yylex);
     }
 
   if (locval && classval)
@@ -4725,22 +4977,7 @@ lookup_name_real (name, prefer_type, nonclass)
   else if (classval)
     val = classval;
   else
-    {
-      /* unscoped lookup of a global, iterate over namespaces,
-         considering using namespace statements */
-      tree binding;
-      tree scope = current_namespace;
-      do
-       {
-         binding = binding_for_name (name, scope);
-         val = BINDING_VALUE (binding);
-         val = lookup_using_namespace (name, val, current_namespace, scope);
-         if (scope == global_namespace)
-           break;
-         scope = DECL_NAMESPACE (scope);
-       }
-      while (!val);
-    }
+    val = unqualified_namespace_lookup (name, prefer_type, namespaces_only);
 
  done:
   if (val)
@@ -4764,6 +5001,9 @@ lookup_name_real (name, prefer_type, nonclass)
       if ((TREE_CODE (val) == TEMPLATE_DECL && looking_for_template)
          || TREE_CODE (val) == TYPE_DECL || prefer_type <= 0)
        ;
+      /* Caller wants a class-or-namespace-name. */
+      else if (prefer_type == 1 && TREE_CODE (val) == NAMESPACE_DECL)
+       ;
       else if (IDENTIFIER_HAS_TYPE_VALUE (name))
        val = TYPE_MAIN_DECL (IDENTIFIER_TYPE_VALUE (name));
       else if (TREE_TYPE (val) == error_mark_node)
@@ -4779,7 +5019,23 @@ tree
 lookup_name_nonclass (name)
      tree name;
 {
-  return lookup_name_real (name, 0, 1);
+  return lookup_name_real (name, 0, 1, 0);
+}
+
+tree
+lookup_function_nonclass (name, args)
+     tree name;
+     tree args;
+{
+  return lookup_arg_dependent (name, lookup_name_nonclass (name), args);
+}
+
+tree
+lookup_name_namespace_only (name)
+     tree name;
+{
+  /* type-or-namespace, nonclass, namespace_only */
+  return lookup_name_real (name, 1, 1, 1);
 }
 
 tree
@@ -4787,7 +5043,7 @@ lookup_name (name, prefer_type)
      tree name;
      int prefer_type;
 {
-  return lookup_name_real (name, prefer_type, 0);
+  return lookup_name_real (name, prefer_type, 0, 0);
 }
 
 /* Similar to `lookup_name' but look only at current binding level.  */
@@ -4798,7 +5054,7 @@ lookup_name_current_level (name)
 {
   register tree t = NULL_TREE;
 
-  if (current_binding_level == global_binding_level)
+  if (current_binding_level->namespace_p)
     {
       t =  IDENTIFIER_NAMESPACE_VALUE (name);
 
@@ -4825,6 +5081,18 @@ lookup_name_current_level (name)
 
   return t;
 }
+
+void
+begin_only_namespace_names ()
+{
+  only_namespace_names = 1;
+}
+
+void
+end_only_namespace_names ()
+{
+  only_namespace_names = 0;
+}
 \f
 /* Arrange for the user to get a source line number, even when the
    compiler is going down in flames, so that she at least has a
@@ -4835,7 +5103,7 @@ lookup_name_current_level (name)
 
 static void
 signal_catch (sig)
-     int sig;
+     int sig ATTRIBUTE_UNUSED;
 {
   signal (SIGSEGV, SIG_DFL);
 #ifdef SIGIOT
@@ -4887,15 +5155,15 @@ record_builtin_type (rid_index, name, type)
       tdecl = pushdecl (build_decl (TYPE_DECL, tname, type));
       set_identifier_type_value (tname, NULL_TREE);
       if ((int) rid_index < (int) RID_MAX)
-       /* builtin types live in the global namespace */
-       IDENTIFIER_GLOBAL_VALUE (tname) = tdecl;
+       /* Built-in types live in the global namespace. */
+       SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl);
     }
   if (rname != NULL_TREE)
     {
       if (tname != NULL_TREE)
        {
          set_identifier_type_value (rname, NULL_TREE);
-         IDENTIFIER_GLOBAL_VALUE (rname) = tdecl;
+         SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl);
        }
       else
        {
@@ -4905,6 +5173,53 @@ record_builtin_type (rid_index, name, type)
     }
 }
 
+/* Record one of the standard Java types.
+ * Declare it as having the given NAME.
+ * If SIZE > 0, it is the size of one of the integral types;
+ * otherwise it is the negative of the size of one of the other types.  */
+
+static tree
+record_builtin_java_type (name, size)
+     char *name;
+     int size;
+{
+  tree type, decl;
+  if (size > 0)
+    type = make_signed_type (size);
+  else if (size > -32)
+    { /* "__java_char" or ""__java_boolean". */
+      type = make_unsigned_type (-size);
+      /*if (size == -1)        TREE_SET_CODE (type, BOOLEAN_TYPE);*/
+    }
+  else
+    { /* "__java_float" or ""__java_double". */
+      type = make_node (REAL_TYPE);
+      TYPE_PRECISION (type) = - size;
+      layout_type (type);
+    }
+  record_builtin_type (RID_MAX, name, type);
+  decl = TYPE_NAME (type);
+  DECL_IGNORED_P (decl) = 1;
+  TYPE_FOR_JAVA (type) = 1;
+  return type;
+}
+
+/* Push a type into the namespace so that the back-ends ignore it. */
+
+static void
+record_unknown_type (type, name)
+     tree type;
+     char *name;
+{
+  tree decl = pushdecl (build_decl (TYPE_DECL, get_identifier (name), type));
+  /* Make sure the "unknown type" typedecl gets ignored for debug info.  */
+  DECL_IGNORED_P (decl) = 1;
+  TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
+  TYPE_SIZE (type) = TYPE_SIZE (void_type_node);
+  TYPE_ALIGN (type) = 1;
+  TYPE_MODE (type) = TYPE_MODE (void_type_node);
+} 
+
 /* Push overloaded decl, in global scope, with one argument so it
    can be used as a callback from define_function.  */
 
@@ -4937,7 +5252,6 @@ auto_function (name, type, code)
 void
 init_decl_processing ()
 {
-  tree decl;
   register tree endlink, int_endlink, double_endlink, unsigned_endlink;
   tree fields[20];
   /* Data type of memcpy.  */
@@ -4956,8 +5270,9 @@ init_decl_processing ()
   /* Have to make these distinct before we try using them.  */
   lang_name_cplusplus = get_identifier ("C++");
   lang_name_c = get_identifier ("C");
+  lang_name_java = get_identifier ("Java");
 
-  /* enter the global namespace */
+  /* Enter the global namespace. */
   my_friendly_assert (global_namespace == NULL_TREE, 375);
   my_friendly_assert (current_lang_name == NULL_TREE, 375);
   current_lang_name = lang_name_cplusplus;
@@ -5024,6 +5339,9 @@ init_decl_processing ()
   /* Make the binding_level structure for global names.  */
   pushlevel (0);
   global_binding_level = current_binding_level;
+  /* The global level is the namespace level of ::.  */
+  NAMESPACE_LEVEL (global_namespace) = global_binding_level;
+  declare_namespace_level ();
 
   this_identifier = get_identifier (THIS_NAME);
   in_charge_identifier = get_identifier (IN_CHARGE_NAME);
@@ -5104,6 +5422,8 @@ init_decl_processing ()
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node));
   intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
+  intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
+  pushdecl (build_decl (TYPE_DECL, NULL_TREE, intTI_type_node));
   unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
   unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode));
@@ -5112,6 +5432,8 @@ init_decl_processing ()
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node));
   unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
+  unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
+  pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intTI_type_node));
 
   float_type_node = make_node (REAL_TYPE);
   TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
@@ -5155,6 +5477,15 @@ init_decl_processing ()
   TREE_TYPE (complex_long_double_type_node) = long_double_type_node;
   layout_type (complex_long_double_type_node);
 
+  java_byte_type_node = record_builtin_java_type ("__java_byte", 8);
+  java_short_type_node = record_builtin_java_type ("__java_short", 16);
+  java_int_type_node = record_builtin_java_type ("__java_int", 32);
+  java_long_type_node = record_builtin_java_type ("__java_long", 64);
+  java_float_type_node = record_builtin_java_type ("__java_float", -32);
+  java_double_type_node = record_builtin_java_type ("__java_double", -64);
+  java_char_type_node = record_builtin_java_type ("__java_char", -16);
+  java_boolean_type_node = record_builtin_java_type ("__java_boolean", -1);
+
   integer_zero_node = build_int_2 (0, 0);
   TREE_TYPE (integer_zero_node) = integer_type_node;
   integer_one_node = build_int_2 (1, 0);
@@ -5210,7 +5541,7 @@ init_decl_processing ()
      initializations of __FUNCTION__ and __PRETTY_FUNCTION__.  */
   array_domain_type = build_index_type (build_int_2 (200, 0));
 
-  /* make a type for arrays of characters.
+  /* Make a type for arrays of characters.
      With luck nothing will ever really depend on the length of this
      array type.  */
   char_array_type_node
@@ -5388,7 +5719,7 @@ init_decl_processing ()
   temp = tree_cons (NULL_TREE,
                    build_pointer_type (build_function_type (void_type_node,
                                                             NULL_TREE)),
-                   ptr_ftype_sizetype);
+                   tree_cons (NULL_TREE, ptr_ftype_sizetype, NULL_TREE));
   builtin_function ("__builtin_apply",
                    build_function_type (ptr_type_node, temp),
                    BUILT_IN_APPLY, NULL_PTR);
@@ -5492,14 +5823,8 @@ init_decl_processing ()
   /* C++ extensions */
 
   unknown_type_node = make_node (UNKNOWN_TYPE);
-  decl = pushdecl (build_decl (TYPE_DECL, get_identifier ("unknown type"),
-                       unknown_type_node));
-  /* Make sure the "unknown type" typedecl gets ignored for debug info.  */
-  DECL_IGNORED_P (decl) = 1;
-  TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
-  TYPE_SIZE (unknown_type_node) = TYPE_SIZE (void_type_node);
-  TYPE_ALIGN (unknown_type_node) = 1;
-  TYPE_MODE (unknown_type_node) = TYPE_MODE (void_type_node);
+  record_unknown_type (unknown_type_node, "unknown type");
+
   /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node.  */
   TREE_TYPE (unknown_type_node) = unknown_type_node;
 
@@ -5617,19 +5942,28 @@ init_decl_processing ()
       record_builtin_type (RID_MAX, SIGTABLE_PTR_TYPE, sigtable_entry_type);
     }
 
-  std_node = build_decl (NAMESPACE_DECL, get_identifier ("std"),
+  std_node = build_decl (NAMESPACE_DECL, 
+                        get_identifier (flag_honor_std ? "fake std":"std"),
                         void_type_node);
   pushdecl (std_node);
 
+  global_type_node = make_node (LANG_TYPE);
+  record_unknown_type (global_type_node, "global type");
+
   /* Now, C++.  */
   current_lang_name = lang_name_cplusplus;
 
   {
-    tree bad_alloc_type_node = xref_tag
+    tree bad_alloc_type_node, newtype, deltype;
+    if (flag_honor_std)
+      push_namespace (get_identifier ("std"));
+    bad_alloc_type_node = xref_tag
       (class_type_node, get_identifier ("bad_alloc"), NULL_TREE, 1);
-    tree newtype = build_exception_variant
+    if (flag_honor_std)
+      pop_namespace ();
+    newtype = build_exception_variant
       (ptr_ftype_sizetype, build_tree_list (NULL_TREE, bad_alloc_type_node));
-    tree deltype = build_exception_variant
+    deltype = build_exception_variant
       (void_ftype_ptr, build_tree_list (NULL_TREE, NULL_TREE));
     auto_function (ansi_opname[(int) NEW_EXPR], newtype, NOT_BUILT_IN);
     auto_function (ansi_opname[(int) VEC_NEW_EXPR], newtype, NOT_BUILT_IN);
@@ -5666,6 +6000,19 @@ init_decl_processing ()
 
   /* Show we use EH for cleanups.  */
   using_eh_for_cleanups ();
+
+  print_error_function = lang_print_error_function;
+  lang_get_alias_set = &c_get_alias_set;
+}
+
+/* Function to print any language-specific context for an error message.  */
+
+static void
+lang_print_error_function (file)
+     char *file;
+{
+  default_print_error_function (file);
+  maybe_print_template_context ();
 }
 
 /* Make a definition for a builtin function named NAME and whose data type
@@ -5689,6 +6036,9 @@ define_function (name, type, function_code, pfn, library_name)
   TREE_PUBLIC (decl) = 1;
   DECL_ARTIFICIAL (decl) = 1;
 
+  my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392);
+  DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
+
   /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
      we cannot change DECL_ASSEMBLER_NAME until we have installed this
      function in the namespace.  */
@@ -5864,9 +6214,10 @@ groktypename (typename)
 int debug_temp_inits = 1;
 
 tree
-start_decl (declarator, declspecs, initialized)
+start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
      tree declarator, declspecs;
      int initialized;
+     tree attributes, prefix_attributes;
 {
   register tree decl;
   register tree type, tem;
@@ -5889,7 +6240,7 @@ start_decl (declarator, declspecs, initialized)
 
   decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
                         NULL_TREE);
-  if (decl == NULL_TREE || decl == void_type_node)
+  if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
     return NULL_TREE;
 
   type = TREE_TYPE (decl);
@@ -5919,6 +6270,18 @@ start_decl (declarator, declspecs, initialized)
       ? DECL_CLASS_CONTEXT (decl)
       : DECL_CONTEXT (decl);
 
+  if (initialized && context && TREE_CODE (context) == NAMESPACE_DECL
+      && context != current_namespace && TREE_CODE (decl) == VAR_DECL)
+    {
+      /* When parsing the initializer, lookup should use the object's
+        namespace. */
+      push_decl_namespace (context);
+    }
+
+  /* We are only interested in class contexts, later. */
+  if (context && TREE_CODE (context) == NAMESPACE_DECL)
+    context = NULL_TREE;
+
   if (initialized)
     /* Is it valid for this decl to have an initializer at all?
        If not, set INITIALIZED to zero, which will indirectly
@@ -6017,26 +6380,30 @@ start_decl (declarator, declspecs, initialized)
        }
 
       /* cp_finish_decl sets DECL_EXTERNAL if DECL_IN_AGGR_P is set.  */
-      if (DECL_LANG_SPECIFIC (decl))
-       DECL_IN_AGGR_P (decl) = 0;
-      if (DECL_USE_TEMPLATE (decl) || CLASSTYPE_USE_TEMPLATE (context))
+      DECL_IN_AGGR_P (decl) = 0;
+      if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) 
+         || CLASSTYPE_USE_TEMPLATE (context))
        SET_DECL_TEMPLATE_SPECIALIZATION (decl);
 
-      /* Stupid stupid stupid stupid  (jason 7/21/95) */
-      if (pedantic && DECL_EXTERNAL (decl)
-         && ! DECL_TEMPLATE_SPECIALIZATION (decl))
+      if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
        cp_pedwarn ("declaration of `%#D' outside of class is not definition",
                    decl);
 
       pushclass (context, 2);
     }
 
+  /* Set attributes here so if duplicate decl, will have proper attributes.  */
+  cplus_decl_attributes (decl, attributes, prefix_attributes);
+
   /* 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 DECL or it may be a previous decl of the same name.  */
   
-  if ((TREE_CODE (decl) != PARM_DECL && DECL_CONTEXT (decl) != NULL_TREE)
-      || (TREE_CODE (decl) == TEMPLATE_DECL && !global_bindings_p ())
+  if ((TREE_CODE (decl) != PARM_DECL && DECL_CONTEXT (decl) != NULL_TREE 
+       /* Definitions of namespace members outside their namespace are
+         possible. */
+       && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
+      || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
       || TREE_CODE (type) == LANG_TYPE
       /* The declaration of template specializations does not affect
         the functions available for overload resolution, so we do not
@@ -6052,7 +6419,7 @@ start_decl (declarator, declspecs, initialized)
       if (! current_function_decl)
        tem = push_template_decl (tem);
       else if (minimal_parse_mode)
-       DECL_VINDEX (decl)
+       DECL_VINDEX (tem)
            = build_min_nt (DECL_STMT, copy_to_permanent (declarator),
                            copy_to_permanent (declspecs),
                            NULL_TREE);
@@ -6192,7 +6559,7 @@ start_decl_1 (decl)
 }
 
 /* Handle initialization of references.
-   These three arguments from from `cp_finish_decl', and have the
+   These three arguments are from `cp_finish_decl', and have the
    same meaning here that they do there.
 
    Quotes on semantics can be found in ARM 8.4.3.  */
@@ -6359,6 +6726,23 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
   if (asmspec_tree)
       asmspec = TREE_STRING_POINTER (asmspec_tree);
 
+  if (init && TREE_CODE (init) == NAMESPACE_DECL)
+    {
+      cp_error ("Cannot initialize `%D' to namespace `%D'",
+               decl, init);
+      init = NULL_TREE;
+    }
+
+  if (TREE_CODE (decl) == VAR_DECL 
+      && DECL_CONTEXT (decl)
+      && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL
+      && DECL_CONTEXT (decl) != current_namespace
+      && init)
+    {
+      /* Leave the namespace of the object. */
+      pop_decl_namespace ();
+    }
+
   /* If the type of the thing we are declaring either has
      a constructor, or has a virtual function table pointer,
      AND its initialization was accepted by `start_decl',
@@ -6634,8 +7018,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
        /* Let debugger know it should output info for this type.  */
        note_debug_info_needed (ttype);
 
-      if (TREE_STATIC (decl) && DECL_CONTEXT (decl)
-         && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
+      if (TREE_STATIC (decl) && DECL_CLASS_SCOPE_P (decl))
        note_debug_info_needed (DECL_CONTEXT (decl));
 
       if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
@@ -6685,35 +7068,20 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
       if (was_temp)
        end_temporary_allocation ();
 
-      /* Extern inline function static data has external linkage.  */
+      /* Extern inline function static data has external linkage.
+         Instead of trying to deal with that, we disable inlining of
+         such functions.  The ASM_WRITTEN check is to avoid hitting this
+         for __FUNCTION__.  */
       if (TREE_CODE (decl) == VAR_DECL
          && TREE_STATIC (decl)
+         && ! TREE_ASM_WRITTEN (decl)
          && current_function_decl
          && DECL_CONTEXT (decl) == current_function_decl
          && DECL_THIS_INLINE (current_function_decl)
          && TREE_PUBLIC (current_function_decl))
        {
-         if (DECL_INTERFACE_KNOWN (current_function_decl))
-           {
-             TREE_PUBLIC (decl) = 1;
-             DECL_EXTERNAL (decl) = DECL_EXTERNAL (current_function_decl);
-           }
-         /* We can only do this if we can use common or weak, and we
-            can't if it has been initialized and we don't support weak.  */
-         else if (DECL_INITIAL (decl) == NULL_TREE
-                  || DECL_INITIAL (decl) == error_mark_node)
-           {
-             TREE_PUBLIC (decl) = 1;
-             DECL_COMMON (decl) = 1;
-           }
-         else if (flag_weak)
-           make_decl_one_only (decl);
-
-         if (TREE_PUBLIC (decl))
-           DECL_ASSEMBLER_NAME (decl)
-             = build_static_name (current_function_decl, DECL_NAME (decl));
-         else if (! DECL_ARTIFICIAL (decl))
-           cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
+         current_function_cannot_inline
+           = "function with static variable cannot be inline";
        }
 
       else if (TREE_CODE (decl) == VAR_DECL
@@ -6737,7 +7105,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
                make_decl_one_only (decl);
              else
                {
-                 /* we can't do anything useful; leave vars for explicit
+                 /* We can't do anything useful; leave vars for explicit
                     instantiation.  */
                  DECL_EXTERNAL (decl) = 1;
                  DECL_NOT_REALLY_EXTERN (decl) = 0;
@@ -6955,7 +7323,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
                 destructor, so we don't complain about the 'resource
                 allocation is initialization' idiom.  */
              /* Now set attribute((unused)) on types so decls of
-                of that type will be marked used. (see TREE_USED, above.) 
+                that type will be marked used. (see TREE_USED, above.) 
                 This avoids the warning problems this particular code
                 tried to work around. */
 
@@ -7281,7 +7649,7 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
 static tree
 grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
            raises, attrlist, check, friendp, publicp, inlinep, funcdef_flag,
-           template_count)
+           template_count, in_namespace)
      tree ctype, type;
      tree declarator;
      tree orig_declarator;
@@ -7289,6 +7657,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
      enum overload_flags flags;
      tree quals, raises, attrlist;
      int check, friendp, publicp, inlinep, funcdef_flag, template_count;
+     tree in_namespace;
 {
   tree cname, decl;
   int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
@@ -7306,10 +7675,14 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
     }
 
   decl = build_lang_decl (FUNCTION_DECL, declarator, type);
-  /* propagate volatile out from type to decl */
+  /* Propagate volatile out from type to decl. */
   if (TYPE_VOLATILE (type))
     TREE_THIS_VOLATILE (decl) = 1;
 
+  /* This decl is not from the current namespace. */
+  if (in_namespace)
+    set_decl_namespace (decl, in_namespace);
+
   /* Should probably propagate const out from type to decl I bet (mrs).  */
   if (staticp)
     {
@@ -7320,7 +7693,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
   if (ctype)
     DECL_CLASS_CONTEXT (decl) = ctype;
 
-  if (ctype == NULL_TREE && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
+  if (ctype == NULL_TREE && MAIN_NAME_P (declarator))
     {
       if (inlinep)
        error ("cannot declare `main' to be inline");
@@ -7362,16 +7735,23 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
        break;
       }
 
-  if (friendp && 
-      TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
+  if (friendp
+      && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
     {
-      /* A friend declaration of the form friend void f<>().  Record
-        the information in the TEMPLATE_ID_EXPR.  */
-      SET_DECL_IMPLICIT_INSTANTIATION (decl);
-      DECL_TEMPLATE_INFO (decl) 
-       = perm_tree_cons (TREE_OPERAND (orig_declarator, 0),
-                         TREE_OPERAND (orig_declarator, 1),
-                         NULL_TREE);
+      if (funcdef_flag)
+       cp_error
+         ("defining explicit specialization `%D' in friend declaration",
+          orig_declarator);
+      else
+       {
+         /* A friend declaration of the form friend void f<>().  Record
+            the information in the TEMPLATE_ID_EXPR.  */
+         SET_DECL_IMPLICIT_INSTANTIATION (decl);
+         DECL_TEMPLATE_INFO (decl)
+           = perm_tree_cons (TREE_OPERAND (orig_declarator, 0),
+                             TREE_OPERAND (orig_declarator, 1),
+                             NULL_TREE);
+       }
     }
 
   /* Caller will do the rest of this.  */
@@ -7398,7 +7778,8 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
                                            2 * (funcdef_flag != 0) + 
                                            4 * (friendp != 0));
 
-      if (check)
+      if ((! TYPE_FOR_JAVA (ctype) || check_java_method (ctype, decl))
+         && check)
        {
          tmp = check_classfn (ctype, decl);
 
@@ -7415,18 +7796,16 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
 
       if (check == 0 && ! current_function_decl)
        {
-         /* assembler names live in the global namespace */
+         /* Assembler names live in the global namespace. */
          tmp = IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl));
          if (tmp == NULL_TREE)
-           IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl;
+           SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl), decl);
          else if (TREE_CODE (tmp) != TREE_CODE (decl))
            cp_error ("inconsistent declarations for `%D'", decl);
          else
            {
              duplicate_decls (decl, tmp);
              decl = tmp;
-             /* avoid creating circularities.  */
-             DECL_CHAIN (decl) = NULL_TREE;
            }
          make_decl_rtl (decl, NULL_PTR, 1);
        }
@@ -7445,8 +7824,9 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
                                            template_count, 
                                            2 * (funcdef_flag != 0) + 
                                            4 * (friendp != 0));
-
-      if (ctype != NULL_TREE && check)
+      if (ctype != NULL_TREE
+         && (! TYPE_FOR_JAVA (ctype) || check_java_method (ctype, decl))
+         && check)
        {
          tmp = check_classfn (ctype, decl);
 
@@ -7490,15 +7870,13 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
                 IDENTIFIER_GLOBAL_VALUE.  */
              tmp = lookup_name (DECL_ASSEMBLER_NAME (decl), 0);
              if (tmp == NULL_TREE)
-               IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl;
+               SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl), decl);
              else if (TREE_CODE (tmp) != TREE_CODE (decl))
                cp_error ("inconsistent declarations for `%D'", decl);
              else
                {
                  duplicate_decls (decl, tmp);
                  decl = tmp;
-                 /* avoid creating circularities.  */
-                 DECL_CHAIN (decl) = NULL_TREE;
                }
            }
 
@@ -7519,12 +7897,13 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
 }
 
 static tree
-grokvardecl (type, declarator, specbits_in, initialized, constp)
+grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
      tree type;
      tree declarator;
      RID_BIT_TYPE *specbits_in;
      int initialized;
      int constp;
+     tree in_namespace;
 {
   tree decl;
   RID_BIT_TYPE specbits;
@@ -7544,12 +7923,16 @@ grokvardecl (type, declarator, specbits_in, initialized, constp)
     }
   else
     {
+      tree context = in_namespace ? in_namespace : current_namespace;
       decl = build_decl (VAR_DECL, declarator, complete_type (type));
-      if (current_namespace != global_namespace)
-       DECL_ASSEMBLER_NAME (decl) =  build_static_name (current_namespace,
+      if (context != global_namespace && namespace_bindings_p ())
+       DECL_ASSEMBLER_NAME (decl) =  build_static_name (context,
                                                         declarator);
     }
 
+  if (in_namespace)
+    set_decl_namespace (decl, in_namespace);
+
   if (RIDBIT_SETP (RID_EXTERN, specbits))
     {
       DECL_THIS_EXTERN (decl) = 1;
@@ -7558,8 +7941,7 @@ grokvardecl (type, declarator, specbits_in, initialized, constp)
 
   /* In class context, static means one per class,
      public access, and static storage.  */
-  if (DECL_FIELD_CONTEXT (decl) != NULL_TREE
-      && IS_AGGR_TYPE (DECL_FIELD_CONTEXT (decl)))
+  if (DECL_CLASS_SCOPE_P (decl))
     {
       TREE_PUBLIC (decl) = 1;
       TREE_STATIC (decl) = 1;
@@ -7611,9 +7993,9 @@ build_ptrmemfunc_type (type)
 
   t = make_lang_type (RECORD_TYPE);
 
-  /* Let the front-end know this is a pointer to member function.  */
+  /* Let the front-end know this is a pointer to member function...  */
   TYPE_PTRMEMFUNC_FLAG (t) = 1;
-  /* and not really an aggregate.  */
+  /* ... and not really an aggregate.  */
   IS_AGGR_TYPE (t) = 0;
 
   fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
@@ -7740,6 +8122,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
   tree quals = NULL_TREE;
   tree raises = NULL_TREE;
   int template_count = 0;
+  tree in_namespace = NULL_TREE;
 
   RIDBIT_RESET_ALL (specbits);
   if (decl_context == FUNCDEF)
@@ -7766,7 +8149,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            next = &TREE_OPERAND (decl, 0);
            break;
 
-         case BIT_NOT_EXPR:    /* for C++ destructors!  */
+         case BIT_NOT_EXPR:    /* For C++ destructors!  */
            {
              tree name = TREE_OPERAND (decl, 0);
              tree rename = NULL_TREE;
@@ -7809,7 +8192,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            break;
 
          case ADDR_EXPR:       /* C++ reference declaration */
-           /* fall through */
+           /* Fall through. */
          case ARRAY_REF:
          case INDIRECT_REF:
            ctype = NULL_TREE;
@@ -7827,7 +8210,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                *next = TREE_OPERAND (decl, 0);
                init = TREE_OPERAND (decl, 1);
 
-               decl = start_decl (declarator, declspecs, 1);
+               decl = start_decl (declarator, declspecs, 1, NULL_TREE, NULL_TREE);
                /* Look for __unused__ attribute */
                if (TREE_USED (TREE_TYPE (decl)))
                  TREE_USED (decl) = 1;
@@ -7871,7 +8254,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                else
                  my_friendly_abort (0);
              }
-         /* fall through */
+         /* Fall through. */
 
          case IDENTIFIER_NODE:
            if (TREE_CODE (decl) == IDENTIFIER_NODE)
@@ -7909,6 +8292,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              tree cname = TREE_OPERAND (decl, 0);
              if (cname == NULL_TREE)
                ctype = NULL_TREE;
+             else if (TREE_CODE (cname) == NAMESPACE_DECL)
+               {
+                 ctype = NULL_TREE;
+                 in_namespace = TREE_OPERAND (decl, 0);
+                 TREE_OPERAND (decl, 0) = NULL_TREE;
+               }
              else if (! is_aggr_type (cname, 1))
                TREE_OPERAND (decl, 0) = NULL_TREE;
              /* Must test TREE_OPERAND (decl, 1), in case user gives
@@ -8111,7 +8500,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                {
                  if (i == (int) RID_LONG && RIDBIT_SETP (i, specbits))
                    {
-                     if (pedantic && ! in_system_header)
+                     if (pedantic && ! in_system_header && warn_long_long)
                        pedwarn ("ANSI C++ does not support `long long'");
                      if (longlong)
                        error ("`long long long' is too long for GCC");
@@ -8389,7 +8778,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
   constp = !! RIDBIT_SETP (RID_CONST, specbits) + TYPE_READONLY (type);
   volatilep = !! RIDBIT_SETP (RID_VOLATILE, specbits) + TYPE_VOLATILE (type);
-  type = TYPE_MAIN_VARIANT (type);
+  type = build_type_variant (type, 0, 0);
   staticp = 0;
   inlinep = !! RIDBIT_SETP (RID_INLINE, specbits);
   virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);
@@ -8457,8 +8846,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
   /* Static anonymous unions are dealt with here.  */
   if (staticp && decl_context == TYPENAME
       && TREE_CODE (declspecs) == TREE_LIST
-      && TREE_CODE (TREE_VALUE (declspecs)) == UNION_TYPE
-      && ANON_AGGRNAME_P (TYPE_IDENTIFIER (TREE_VALUE (declspecs))))
+      && ANON_UNION_TYPE_P (TREE_VALUE (declspecs)))
     decl_context = FIELD;
 
   /* Give error if `const,' `volatile,' `inline,' `friend,' or `virtual'
@@ -8644,7 +9032,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
            /* Check for some types that there cannot be arrays of.  */
 
-           if (TYPE_MAIN_VARIANT (type) == void_type_node)
+           if (TREE_CODE (type) == VOID_TYPE)
              {
                cp_error ("declaration of `%D' as array of voids", dname);
                type = error_mark_node;
@@ -8699,7 +9087,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                   the function; then build_vec_delete will need this
                   value.  */
                int yes = suspend_momentary ();
-               /* might be a cast */
+               /* Might be a cast. */
                if (TREE_CODE (size) == NOP_EXPR
                    && TREE_TYPE (size) == TREE_TYPE (TREE_OPERAND (size, 0)))
                  size = TREE_OPERAND (size, 0);
@@ -8891,7 +9279,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                          return void_type_node;
                      }
                  }
-               else            /* it's a constructor.  */
+               else            /* It's a constructor.  */
                  {
                    if (explicitp == 1)
                      explicitp = 2;
@@ -9083,7 +9471,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                }
              else
                {
-                 if (TYPE_MAIN_VARIANT (type) == void_type_node)
+                 if (TREE_CODE (type) == VOID_TYPE)
                    error ("invalid type: `void &'");
                  else
                    type = build_reference_type (type);
@@ -9154,8 +9542,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            if (TREE_COMPLEXITY (declarator) == 0)
              /* This needs to be here, in case we are called
                 multiple times.  */ ;
+           else if (TREE_COMPLEXITY (declarator) == -1)
+             /* Namespace member. */
+             pop_decl_namespace ();
            else if (friendp && (TREE_COMPLEXITY (declarator) < 2))
-             /* don't fall out into global scope. Hides real bug? --eichin */ ;
+             /* Don't fall out into global scope. Hides real bug? --eichin */ ;
            else if (! IS_AGGR_TYPE_CODE
                     (TREE_CODE (TREE_OPERAND (declarator, 0))))
              ;
@@ -9244,7 +9635,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                else if (RIDBIT_SETP (RID_TYPEDEF, specbits)
                         || TYPE_SIZE (complete_type (ctype)) != NULL_TREE)
                  {
-                   /* have to move this code elsewhere in this function.
+                   /* Have to move this code elsewhere in this function.
                       this code is used for i.e., typedef int A::M; M *pm;
 
                       It is?  How? jason 10/2/94 */
@@ -9346,6 +9737,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
         in typenames, fields or parameters.  */
       if (constp || volatilep)
        type = cp_build_type_variant (type, constp, volatilep);
+      if (current_lang_name == lang_name_java)
+       TYPE_FOR_JAVA (type) = 1;
 
       if (decl_context == FIELD)
        {
@@ -9357,27 +9750,46 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1;
        }
       else
-       decl = build_decl (TYPE_DECL, declarator, type);
+       {
+         /* Make sure this typedef lives as long as its type,
+            since it might be used as a template parameter. */
+         if (type != error_mark_node)
+           push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
+         decl = build_decl (TYPE_DECL, declarator, type);
+         if (type != error_mark_node)
+           pop_obstacks ();
+       }
 
       /* If the user declares "struct {...} foo" then `foo' will have
         an anonymous name.  Fill that name in now.  Nothing can
         refer to it, so nothing needs know about the name change.
         The TYPE_NAME field was filled in by build_struct_xref.  */
       if (type != error_mark_node
+         && !TYPE_READONLY (type) && !TYPE_VOLATILE (type)
          && TYPE_NAME (type)
          && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
          && ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
        {
-         /* replace the anonymous name with the real name everywhere.  */
+         /* Replace the anonymous name with the real name everywhere.  */
          lookup_tag_reverse (type, declarator);
          TYPE_NAME (type) = decl;
 
          if (TYPE_LANG_SPECIFIC (type))
            TYPE_WAS_ANONYMOUS (type) = 1;
 
+         /* XXX Temporarily set the scope. 
+            When returning, start_decl expects it as NULL_TREE,
+            and will then then set it using pushdecl. */
+         my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 980404);
+         if (current_class_type)
+           DECL_CONTEXT (decl) = current_class_type;
+         else
+           DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
+
          DECL_ASSEMBLER_NAME (decl) = DECL_NAME (decl);
          DECL_ASSEMBLER_NAME (decl)
            = get_identifier (build_overload_name (type, 1, 1));
+         DECL_CONTEXT (decl) = NULL_TREE;
        }
 
       if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE)
@@ -9497,7 +9909,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
      We don't complain about parms either, but that is because
      a better error message can be made later.  */
 
-  if (TYPE_MAIN_VARIANT (type) == void_type_node && decl_context != PARM)
+  if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM)
     {
       if (! declarator)
        error ("unnamed variable or field declared void");
@@ -9539,7 +9951,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          type = build_pointer_type (type);
        else if (TREE_CODE (type) == OFFSET_TYPE)
          type = build_pointer_type (type);
-       else if (type == void_type_node && declarator)
+       else if (TREE_CODE (type) == VOID_TYPE && declarator)
          {
            error ("declaration of `%s' as void", name);
            return NULL_TREE;
@@ -9638,7 +10050,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                               declarator,
                               virtualp, flags, quals, raises, attrlist,
                               friendp ? -1 : 0, friendp, publicp, inlinep,
-                              funcdef_flag, template_count);
+                              funcdef_flag, template_count, in_namespace);
            if (decl == NULL_TREE)
              return NULL_TREE;
 #if 0
@@ -9659,7 +10071,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            decl = grokfndecl (ctype, type, declarator, declarator,
                               virtualp, flags, quals, raises, attrlist,
                               friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,
-                              template_count);
+                              template_count, in_namespace);
            if (decl == NULL_TREE)
              return NULL_TREE;
          }
@@ -9756,7 +10168,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  cp_error ("ANSI C++ forbids in-class initialization of non-const static member `%D'",
                            declarator);
                
-               if (pedantic && ! INTEGRAL_TYPE_P (type))
+               if (pedantic && ! INTEGRAL_TYPE_P (type) 
+                   && !uses_template_parms (type))
                  cp_pedwarn ("ANSI C++ forbids initialization of member constant `%D' of non-integral type `%T'", declarator, type);
              }
 
@@ -9832,9 +10245,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
            if (current_lang_name == lang_name_cplusplus
                && ! processing_template_decl
-               && ! (IDENTIFIER_LENGTH (original_name) == 4
-                     && IDENTIFIER_POINTER (original_name)[0] == 'm'
-                     && strcmp (IDENTIFIER_POINTER (original_name), "main") == 0)
+               && ! MAIN_NAME_P (original_name)
                && ! (IDENTIFIER_LENGTH (original_name) > 10
                      && IDENTIFIER_POINTER (original_name)[0] == '_'
                      && IDENTIFIER_POINTER (original_name)[1] == '_'
@@ -9857,19 +10268,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                           virtualp, flags, quals, raises, attrlist,
                           1, friendp,
                           publicp, inlinep, funcdef_flag, 
-                          template_count);
+                          template_count, in_namespace);
        if (decl == NULL_TREE)
          return NULL_TREE;
 
+       /* Among other times, could occur from check_explicit_specialization
+          returning an error_mark_node.  */
+       if (decl == error_mark_node)
+         return error_mark_node;
+
        if (ctype == NULL_TREE && DECL_LANGUAGE (decl) != lang_c
            && (! DECL_USE_TEMPLATE (decl) ||
                name_mangling_version < 1)) 
-#if 0
-       /* XXX is support for the old __ns_ mangling really needed? MvL */
-         DECL_ASSEMBLER_NAME (decl) = current_namespace_id (declarator);
-#else
          DECL_ASSEMBLER_NAME (decl) = declarator;
-#endif 
        
        if (staticp == 1)
          {
@@ -9927,7 +10338,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          }
 
        /* An uninitialized decl with `extern' is a reference.  */
-       decl = grokvardecl (type, declarator, &specbits, initialized, constp);
+       decl = grokvardecl (type, declarator, &specbits, 
+                           initialized, constp, in_namespace);
        bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE,
                        inlinep, friendp, raises != NULL_TREE);
 
@@ -10118,7 +10530,7 @@ grokparms (first_parm, funcdef_flag)
     }
   else if (first_parm != NULL_TREE
           && TREE_CODE (TREE_VALUE (first_parm)) != TREE_LIST
-          && TREE_VALUE (first_parm) != void_type_node)
+          && TREE_CODE (TREE_VALUE (first_parm)) != VOID_TYPE)
     my_friendly_abort (145);
   else
     {
@@ -10140,7 +10552,8 @@ grokparms (first_parm, funcdef_flag)
 
              chain = TREE_CHAIN (parm);
              /* @@ weak defense against parse errors.  */
-             if (decl != void_type_node && TREE_CODE (decl) != TREE_LIST)
+             if (TREE_CODE (decl) != VOID_TYPE 
+                 && TREE_CODE (decl) != TREE_LIST)
                {
                  /* Give various messages as the need arises.  */
                  if (TREE_CODE (decl) == STRING_CST)
@@ -10150,7 +10563,7 @@ grokparms (first_parm, funcdef_flag)
                  continue;
                }
 
-             if (decl != void_type_node)
+             if (TREE_CODE (decl) != VOID_TYPE)
                {
                  decl = grokdeclarator (TREE_VALUE (decl),
                                         TREE_PURPOSE (decl),
@@ -10159,7 +10572,7 @@ grokparms (first_parm, funcdef_flag)
                  if (! decl)
                    continue;
                  type = TREE_TYPE (decl);
-                 if (TYPE_MAIN_VARIANT (type) == void_type_node)
+                 if (TREE_CODE (type) == VOID_TYPE)
                    decl = void_type_node;
                  else if (TREE_CODE (type) == METHOD_TYPE)
                    {
@@ -10188,18 +10601,18 @@ grokparms (first_parm, funcdef_flag)
                            && CLASSTYPE_ABSTRACT_VIRTUALS (type))
                     {
                       abstract_virtuals_error (decl, type);
-                      any_error = 1;  /* seems like a good idea */
+                      any_error = 1;  /* Seems like a good idea. */
                     }
                   else if (TREE_CODE (type) == RECORD_TYPE
                            && TYPE_LANG_SPECIFIC (type)
                            && IS_SIGNATURE (type))
                     {
                       signature_error (decl, type);
-                      any_error = 1;  /* seems like a good idea */
+                      any_error = 1;  /* Seems like a good idea. */
                     }
                }
 
-             if (decl == void_type_node)
+             if (TREE_CODE (decl) == VOID_TYPE)
                {
                  if (result == NULL_TREE)
                    {
@@ -10256,6 +10669,7 @@ grokparms (first_parm, funcdef_flag)
                      else
                        init = require_instantiated_type (type, init, integer_zero_node);
                      if (! processing_template_decl
+                         && init != error_mark_node
                          && TREE_CODE (init) != DEFAULT_ARG
                          && ! can_convert_arg (type, TREE_TYPE (init), init))
                        cp_pedwarn ("invalid type `%T' for default argument to `%#D'",
@@ -10364,41 +10778,33 @@ grok_ctor_properties (ctype, decl)
      added to any ctor so we can tell if the class has been initialized
      yet.  This could screw things up in this function, so we deliberately
      ignore the leading int if we're in that situation.  */
-  if (parmtypes
-      && TREE_VALUE (parmtypes) == integer_type_node
-      && TYPE_USES_VIRTUAL_BASECLASSES (ctype))
+  if (TYPE_USES_VIRTUAL_BASECLASSES (ctype))
     {
+      my_friendly_assert (parmtypes
+                         && TREE_VALUE (parmtypes) == integer_type_node,
+                         980529);
       parmtypes = TREE_CHAIN (parmtypes);
       parmtype = TREE_VALUE (parmtypes);
     }
 
   if (TREE_CODE (parmtype) == REFERENCE_TYPE
-      && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == ctype)
-    {
-      if (TREE_CHAIN (parmtypes) == NULL_TREE
+      && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == ctype
+      && (TREE_CHAIN (parmtypes) == NULL_TREE
          || TREE_CHAIN (parmtypes) == void_list_node
-         || TREE_PURPOSE (TREE_CHAIN (parmtypes)))
-       {
-         TYPE_HAS_INIT_REF (ctype) = 1;
-         if (TYPE_READONLY (TREE_TYPE (parmtype)))
-           TYPE_HAS_CONST_INIT_REF (ctype) = 1;
-       }
-      else
-       TYPE_GETS_INIT_AGGR (ctype) = 1;
+         || TREE_PURPOSE (TREE_CHAIN (parmtypes))))
+    {
+      TYPE_HAS_INIT_REF (ctype) = 1;
+      if (TYPE_READONLY (TREE_TYPE (parmtype)))
+       TYPE_HAS_CONST_INIT_REF (ctype) = 1;
     }
-  else if (TYPE_MAIN_VARIANT (parmtype) == ctype)
+  else if (TYPE_MAIN_VARIANT (parmtype) == ctype
+          && TREE_CHAIN (parmtypes) != NULL_TREE
+          && TREE_CHAIN (parmtypes) == void_list_node)
     {
-      if (TREE_CHAIN (parmtypes) != NULL_TREE
-         && TREE_CHAIN (parmtypes) == void_list_node)
-       {
-         cp_error ("invalid constructor; you probably meant `%T (const %T&)'",
-                   ctype, ctype);
-         SET_IDENTIFIER_ERROR_LOCUS (DECL_NAME (decl), ctype);
-
-         return 0;
-       }
-      else
-       TYPE_GETS_INIT_AGGR (ctype) = 1;
+      cp_error ("invalid constructor; you probably meant `%T (const %T&)'",
+               ctype, ctype);
+      SET_IDENTIFIER_ERROR_LOCUS (DECL_NAME (decl), ctype);
+      return 0;
     }
   else if (TREE_CODE (parmtype) == VOID_TYPE
           || TREE_PURPOSE (parmtypes) != NULL_TREE)
@@ -10527,7 +10933,7 @@ grok_op_properties (decl, virtualp, friendp)
                cp_error ("`%D' must be either a non-static member function or a non-member function", decl);
 
              if (p)
-               for (; TREE_VALUE (p) != void_type_node ; p = TREE_CHAIN (p))
+               for (; TREE_CODE (TREE_VALUE (p)) != VOID_TYPE ; p = TREE_CHAIN (p))
                  {
                    tree arg = TREE_VALUE (p);
                    if (TREE_CODE (arg) == REFERENCE_TYPE)
@@ -10549,7 +10955,7 @@ grok_op_properties (decl, virtualp, friendp)
        }
       
       if (name == ansi_opname[(int) CALL_EXPR])
-       return;                 /* no restrictions on args */
+       return;                 /* No restrictions on args. */
 
       if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl))
        {
@@ -10736,6 +11142,17 @@ xref_tag (code_type_node, name, binfo, globalize)
   register tree ref, t;
   struct binding_level *b = inner_binding_level;
   int got_type = 0;
+  tree attributes = NULL_TREE;
+
+  /* If we are called from the parser, code_type_node will sometimes be a
+     TREE_LIST.  This indicates that the user wrote
+     "class __attribute__ ((foo)) bar".  Extract the attributes so we can
+     use them later.  */
+  if (TREE_CODE (code_type_node) == TREE_LIST)
+    {
+      attributes = TREE_PURPOSE (code_type_node);
+      code_type_node = TREE_VALUE (code_type_node);
+    }
 
   tag_code = (enum tag_types) TREE_INT_CST_LOW (code_type_node);
   switch (tag_code)
@@ -10797,6 +11214,15 @@ xref_tag (code_type_node, name, binfo, globalize)
        {
          /* Try finding it as a type declaration.  If that wins, use it.  */
          ref = lookup_name (name, 1);
+
+         if (ref != NULL_TREE
+             && processing_template_decl
+             && DECL_CLASS_TEMPLATE_P (ref)
+             && template_class_depth (current_class_type) == 0)
+           /* Since GLOBALIZE is true, we're declaring a global
+              template, so we want this type.  */
+           ref = DECL_RESULT (ref);
+
          if (ref && TREE_CODE (ref) == TYPE_DECL
              && TREE_CODE (TREE_TYPE (ref)) == code)
            ref = TREE_TYPE (ref);
@@ -10873,17 +11299,15 @@ xref_tag (code_type_node, name, binfo, globalize)
       /* If it no longer looks like a nested type, make sure it's
         in global scope.  
          If it is not an IDENTIFIER, this is not a declaration */
-      if (b == global_binding_level && !class_binding_level
+      if (b->namespace_p && !class_binding_level
          && TREE_CODE (name) == IDENTIFIER_NODE)
        {
-         tree binding;
-         binding = binding_for_name (name, current_namespace);
-         if (BINDING_VALUE (binding) == NULL_TREE)
-           BINDING_VALUE (binding) = TYPE_NAME (ref);
+         if (IDENTIFIER_NAMESPACE_VALUE (name) == NULL_TREE)
+           SET_IDENTIFIER_NAMESPACE_VALUE (name, TYPE_NAME (ref));
        }
 
       if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref))
-       redeclare_class_template (ref);
+       redeclare_class_template (ref, current_template_parms);
     }
 
   if (binfo)
@@ -10904,6 +11328,8 @@ xref_tag (code_type_node, name, binfo, globalize)
 
   pop_obstacks ();
 
+  TREE_TYPE (ref) = attributes;
+
   return ref;
 }
 
@@ -10970,10 +11396,6 @@ xref_basetypes (code_type_node, name, ref, binfo)
       tree basetype = TREE_VALUE (binfo);
       tree base_binfo;
 
-      GNU_xref_hier (IDENTIFIER_POINTER (name),
-                    IDENTIFIER_POINTER (TREE_VALUE (binfo)),
-                    via_public, via_virtual, 0);
-
       if (basetype && TREE_CODE (basetype) == TYPE_DECL)
        basetype = TREE_TYPE (basetype);
       if (!basetype
@@ -10986,11 +11408,14 @@ xref_basetypes (code_type_node, name, ref, binfo)
                    TREE_VALUE (binfo));
          continue;
        }
+
+      GNU_xref_hier (name, basetype, via_public, via_virtual, 0);
+
 #if 1
       /* This code replaces similar code in layout_basetypes.
          We put the complete_type first for implicit `typename'.  */
-      else if (TYPE_SIZE (complete_type (basetype)) == NULL_TREE
-              && ! (current_template_parms && uses_template_parms (basetype)))
+      if (TYPE_SIZE (complete_type (basetype)) == NULL_TREE
+         && ! (current_template_parms && uses_template_parms (basetype)))
        {
          cp_error ("base class `%T' has incomplete type", basetype);
          continue;
@@ -11007,6 +11432,10 @@ xref_basetypes (code_type_node, name, ref, binfo)
              continue;
            }
 
+         if (TYPE_FOR_JAVA (basetype)
+             && current_lang_stack == current_lang_base)
+           TYPE_FOR_JAVA (ref) = 1;
+
          /* Note that the BINFO records which describe individual
             inheritances are *not* shared in the lattice!  They
             cannot be shared because a given baseclass may be
@@ -11078,8 +11507,13 @@ start_enum (name)
   register tree enumtype = NULL_TREE;
   struct binding_level *b = inner_binding_level;
 
+  /* We are wasting space here and putting these on the permanent_obstack so
+     that typeid(local enum) will work correctly. */
+#if 0
   if (processing_template_decl && current_function_decl)
-    end_temporary_allocation ();
+#endif
+   
+  end_temporary_allocation ();
 
   /* If this is the real definition for a previous forward reference,
      fill in the contents in the same object that used to be the
@@ -11214,7 +11648,7 @@ finish_enum (enumtype, values)
   }
 
   /* Finish debugging output for this type.  */
-  rest_of_type_compilation (enumtype, global_bindings_p ());
+  rest_of_type_compilation (enumtype, namespace_bindings_p ());
 
   return enumtype;
 }
@@ -11375,7 +11809,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
   int doing_friend = 0;
 
   /* Sanity check.  */
-  my_friendly_assert (TREE_VALUE (void_list_node) == void_type_node, 160);
+  my_friendly_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE, 160);
   my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161);
 
   /* Assume, until we see it does.  */
@@ -11409,7 +11843,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
 
       if (! DECL_ARGUMENTS (decl1)
          && !DECL_STATIC_FUNCTION_P (decl1)
-         && DECL_CONTEXT (decl1)
+         && DECL_CLASS_SCOPE_P (decl1)
          && TYPE_IDENTIFIER (DECL_CONTEXT (decl1))
          && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (DECL_CONTEXT (decl1))))
        {
@@ -11484,9 +11918,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
 
       if (TREE_CODE (fntype) == METHOD_TYPE)
        ctype = TYPE_METHOD_BASETYPE (fntype);
-      else if (IDENTIFIER_LENGTH (DECL_NAME (decl1)) == 4
-              && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (decl1)), "main")
-              && DECL_CONTEXT (decl1) == NULL_TREE)
+      else if (DECL_MAIN_P (decl1))
        {
          /* If this doesn't return integer_type, complain.  */
          if (TREE_TYPE (TREE_TYPE (decl1)) != integer_type_node)
@@ -11550,7 +11982,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
   /* Effective C++ rule 15.  See also c_expand_return.  */
   if (warn_ecpp
       && DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR]
-      && TREE_TYPE (fntype) == void_type_node)
+      && TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE)
     cp_warning ("`operator=' should return a reference to `*this'");
 
   /* Make the init_value nonzero so pushdecl knows this is not tentative.
@@ -11570,9 +12002,18 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
   else if (pre_parsed_p == 0)
     {
       /* A specialization is not used to guide overload resolution.  */
-      if (flag_guiding_decls 
-         || !DECL_TEMPLATE_SPECIALIZATION (decl1))
+      if ((flag_guiding_decls 
+          || !DECL_TEMPLATE_SPECIALIZATION (decl1))
+         && ! DECL_FUNCTION_MEMBER_P (decl1))
        decl1 = pushdecl (decl1);
+      else
+       {
+         /* We need to set the DECL_CONTEXT. */
+         if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1))
+           DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1));
+         /* And make sure we have enough default args.  */
+         check_default_args (decl1);
+       }
       DECL_MAIN_VARIANT (decl1) = decl1;
       fntype = TREE_TYPE (decl1);
     }
@@ -11808,7 +12249,7 @@ store_parm_decls ()
                {
                  pushdecl (parm);
                }
-             else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node)
+             else if (TREE_CODE (TREE_TYPE (parm)) == VOID_TYPE)
                cp_error ("parameter `%D' declared void", parm);
              else
                {
@@ -11876,13 +12317,8 @@ store_parm_decls ()
 
   /* If this function is `main', emit a call to `__main'
      to run global initializers, etc.  */
-  if (DECL_NAME (fndecl)
-      && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4
-      && strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0
-      && DECL_CONTEXT (fndecl) == NULL_TREE)
-    {
-      expand_main_function ();
-    }
+  if (DECL_MAIN_P (fndecl))
+    expand_main_function ();
 
   /* Now that we have initialized the parms, we can start their
      cleanups.  We cannot do this before, since expand_decl_cleanup
@@ -12165,20 +12601,22 @@ finish_function (lineno, call_poplevel, nested)
          virtual_size = c_sizeof (current_class_type);
 
          /* At the end, call delete if that's what's requested.  */
-         if (TYPE_GETS_REG_DELETE (current_class_type))
-           /* This NOP_EXPR means we are in a static call context.  */
-           exprstmt
-             = build_method_call (build_indirect_ref (build1 (NOP_EXPR,
-                                                              build_pointer_type (current_class_type),
-                                                              error_mark_node),
-                                                      NULL_PTR),
-                                  ansi_opname[(int) DELETE_EXPR],
-                                  expr_tree_cons (NULL_TREE, current_class_ptr,
-                                             build_expr_list (NULL_TREE, virtual_size)),
-                                  NULL_TREE, LOOKUP_NORMAL);
-         else if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
-           exprstmt = build_x_delete (ptr_type_node, current_class_ptr, 0,
-                                      virtual_size);
+
+         /* FDIS sez: At the point of definition of a virtual destructor
+              (including an implicit definition), non-placement operator
+              delete shall be looked up in the scope of the destructor's
+              class and if found shall be accessible and unambiguous.
+
+            This is somewhat unclear, but I take it to mean that if the
+            class only defines placement deletes we don't do anything here.
+            So we pass LOOKUP_SPECULATIVELY; delete_sanity will complain
+            for us if they ever try to delete one of these.  */
+
+         if (TYPE_GETS_REG_DELETE (current_class_type)
+             || TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
+           exprstmt = build_op_delete_call
+             (DELETE_EXPR, current_class_ptr, virtual_size,
+              LOOKUP_NORMAL | LOOKUP_SPECULATIVELY, NULL_TREE);
          else
            exprstmt = NULL_TREE;
 
@@ -12259,10 +12697,10 @@ finish_function (lineno, call_poplevel, nested)
                  expand_end_bindings (decls, decls != NULL_TREE, 0);
                  poplevel (decls != NULL_TREE, 0, 0);
                }
-             c_expand_return (current_class_ptr);
+             /* c_expand_return knows to return 'this' from a constructor.  */
+             c_expand_return (NULL_TREE);
            }
-         else if (TYPE_MAIN_VARIANT (TREE_TYPE (
-                                                DECL_RESULT (current_function_decl))) != void_type_node
+         else if (TREE_CODE (TREE_TYPE (DECL_RESULT (current_function_decl))) != VOID_TYPE
                   && return_label != NULL_RTX)
            no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
 
@@ -12327,14 +12765,13 @@ finish_function (lineno, call_poplevel, nested)
              poplevel (decls != NULL_TREE, 1, 0);
            }
 
-         c_expand_return (current_class_ptr);
+         /* c_expand_return knows to return 'this' from a constructor.  */
+         c_expand_return (NULL_TREE);
 
          current_function_assigns_this = 0;
          current_function_just_assigned_this = 0;
        }
-      else if (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4
-              && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main")
-              && DECL_CONTEXT (fndecl) == NULL_TREE)
+      else if (DECL_MAIN_P (fndecl))
        {
          /* Make it so that `main' always returns 0 by default.  */
 #ifdef VMS
@@ -12379,7 +12816,7 @@ finish_function (lineno, call_poplevel, nested)
 
       if (cleanup_label)
        {
-         /* remove the binding contour which is used
+         /* Remove the binding contour which is used
             to catch cleanup-generated temporaries.  */
          expand_end_bindings (0, 0, 0);
          poplevel (0, 0, 0);
@@ -12415,7 +12852,7 @@ finish_function (lineno, call_poplevel, nested)
     my_friendly_abort (122);
   poplevel (1, 0, 1);
 
-  /* reset scope for C++: if we were in the scope of a class,
+  /* Reset scope for C++: if we were in the scope of a class,
      then when we finish this function, we are not longer so.
      This cannot be done until we know for sure that no more
      class members will ever be referenced in this function
@@ -12501,7 +12938,7 @@ finish_function (lineno, call_poplevel, nested)
        cp_warning ("`noreturn' function `%D' does return", fndecl);
       else if ((warn_return_type || pedantic)
               && current_function_returns_null
-              && TYPE_MAIN_VARIANT (TREE_TYPE (fntype)) != void_type_node)
+              && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE)
        {
          /* If this function returns non-void and control can drop through,
             complain.  */
@@ -12593,7 +13030,7 @@ start_method (declspecs, declarator)
     return NULL_TREE;
 
   /* Pass friends other than inline friend functions back.  */
-  if (TYPE_MAIN_VARIANT (fndecl) == void_type_node)
+  if (fndecl == void_type_node)
     return fndecl;
 
   if (TREE_CODE (fndecl) != FUNCTION_DECL)
@@ -12607,7 +13044,8 @@ start_method (declspecs, declarator)
     {
       if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (fndecl)) != current_class_type)
        {
-         if (DECL_CONTEXT (fndecl))
+         if (DECL_CONTEXT (fndecl) 
+             && TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
            cp_error ("`%D' is already defined in class %s", fndecl,
                             TYPE_NAME_STRING (DECL_CONTEXT (fndecl)));
        }
@@ -12630,14 +13068,6 @@ start_method (declspecs, declarator)
 
   if (! DECL_FRIEND_P (fndecl))
     {
-      if (DECL_CHAIN (fndecl) != NULL_TREE)
-       {
-         /* Need a fresh node here so that we don't get circularity
-            when we link these together.  If FNDECL was a friend, then
-            `pushdecl' does the right thing, which is nothing wrt its
-            current value of DECL_CHAIN.  */
-         fndecl = copy_node (fndecl);
-       }
       if (TREE_CHAIN (fndecl))
        {
          fndecl = copy_node (fndecl);
@@ -12684,7 +13114,7 @@ finish_method (decl)
 
   register tree link;
 
-  if (TYPE_MAIN_VARIANT (decl) == void_type_node)
+  if (decl == void_type_node)
     return decl;
 
   old_initial = DECL_INITIAL (fndecl);
@@ -12717,7 +13147,7 @@ finish_method (decl)
     IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
   for (link = current_binding_level->type_shadowed;
        link; link = TREE_CHAIN (link))
-    IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
+    SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));
 
   GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level,
                      (HOST_WIDE_INT) current_binding_level->level_chain,
@@ -12896,6 +13326,12 @@ cplus_expand_expr_stmt (exp)
         libg++ to miscompile, and tString to core dump.  */
       exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
 #endif
+
+      /* Strip unused implicit INDIRECT_REFs of references.  */
+      if (TREE_CODE (exp) == INDIRECT_REF
+         && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE)
+       exp = TREE_OPERAND (exp, 0);
+
       /* If we don't do this, we end up down inside expand_expr
         trying to do TYPE_MODE on the ERROR_MARK, and really
         go outside the bounds of the type.  */