OSDN Git Service

* class.c (pushclass): Remove #if 0'd code.
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 0dc17c1..a07f6a9 100644 (file)
@@ -43,6 +43,7 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "../hash.h"
 #include "ggc.h"
+#include "tm_p.h"
 
 extern int current_class_depth;
 
@@ -79,27 +80,7 @@ extern int (*valid_lang_attribute) PARAMS ((tree, tree, tree, tree));
 #define WCHAR_TYPE "int"
 #endif
 
-#ifndef WINT_TYPE
-#define WINT_TYPE "unsigned int"
-#endif
-
-#ifndef INTMAX_TYPE
-#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)    \
-                    ? "int"                                    \
-                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
-                       ? "long int"                            \
-                       : "long long int"))
-#endif
-
-#ifndef UINTMAX_TYPE
-#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)   \
-                    ? "unsigned int"                           \
-                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
-                       ? "long unsigned int"                   \
-                       : "long long unsigned int"))
-#endif
-
-static tree grokparms                          PARAMS ((tree, int));
+static tree grokparms                          PARAMS ((tree));
 static const char *redeclaration_error_message PARAMS ((tree, tree));
 
 static void push_binding_level PARAMS ((struct binding_level *, int,
@@ -187,7 +168,7 @@ static tree start_cleanup_fn PARAMS ((void));
 static void end_cleanup_fn PARAMS ((void));
 static tree cp_make_fname_decl PARAMS ((tree, const char *, int));
 static void initialize_predefined_identifiers PARAMS ((void));
-static tree check_special_function_return_type 
+static tree check_special_function_return_type
   PARAMS ((special_function_kind, tree, tree, tree));
 static tree push_cp_library_fn PARAMS ((enum tree_code, tree));
 static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
@@ -490,7 +471,7 @@ struct binding_level
        replaced with a TEMPLATE_DECL.  */
     unsigned template_parms_p : 1;
 
-    /* Nonzero if this scope corresponds to the `<>' in a 
+    /* Nonzero if this scope corresponds to the `<>' in a
        `template <>' clause.  Whenever this flag is set,
        TEMPLATE_PARMS_P will be set as well.  */
     unsigned template_spec_p : 1;
@@ -565,7 +546,7 @@ push_binding_level (newlevel, tag_transparent, keep)
 {
   /* Add this level to the front of the chain (stack) of levels that
      are active.  */
-  bzero ((char*) newlevel, sizeof (struct binding_level));
+  memset ((char*) newlevel, 0, sizeof (struct binding_level));
   newlevel->level_chain = current_binding_level;
   current_binding_level = newlevel;
   newlevel->tag_transparent = tag_transparent;
@@ -1925,20 +1906,8 @@ wrapup_globals_for_namespace (namespace, data)
 
   /* Process the decls in reverse order--earliest first.
      Put them into VEC from back to front, then take out from front.  */
-
   for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
-    {
-      /* Pretend we've output an unused static variable.  This ensures
-         that the toplevel __FUNCTION__ etc won't be emitted, unless
-         needed. */
-      if (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)
-         && !TREE_PUBLIC (decl) && !TREE_USED (decl))
-       {
-         TREE_ASM_WRITTEN (decl) = 1;
-         DECL_IGNORED_P (decl) = 1;
-       }
-      vec[len - i - 1] = decl;
-    }
+    vec[len - i - 1] = decl;
 
   if (last_time)
     {
@@ -2456,6 +2425,8 @@ store_bindings (names, old_bindings)
      tree names, old_bindings;
 {
   tree t;
+  tree search_bindings = old_bindings;
+
   for (t = names; t; t = TREE_CHAIN (t))
     {
       tree binding, t1, id;
@@ -2472,22 +2443,18 @@ store_bindings (names, old_bindings)
          || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
        continue;
 
-      for (t1 = old_bindings; t1; t1 = TREE_CHAIN (t1))
+      for (t1 = search_bindings; t1; t1 = TREE_CHAIN (t1))
        if (TREE_VEC_ELT (t1, 0) == id)
          goto skip_it;
 
+      my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
       binding = make_tree_vec (4);
-
-      if (id)
-       {
-         my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
-         TREE_VEC_ELT (binding, 0) = id;
-         TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id);
-         TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id);
-         TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);
-         IDENTIFIER_BINDING (id) = NULL_TREE;
-         IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
-       }
+      TREE_VEC_ELT (binding, 0) = id;
+      TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id);
+      TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id);
+      TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);
+      IDENTIFIER_BINDING (id) = NULL_TREE;
+      IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
       TREE_CHAIN (binding) = old_bindings;
       old_bindings = binding;
     skip_it:
@@ -2581,12 +2548,10 @@ pop_from_top_level ()
   for (t = s->old_bindings; t; t = TREE_CHAIN (t))
     {
       tree id = TREE_VEC_ELT (t, 0);
-      if (id)
-       {
-         SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1));
-         IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2);
-         IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
-       }
+
+      SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1));
+      IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2);
+      IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
     }
 
   /* If we were in the middle of compiling a function, restore our
@@ -2859,12 +2824,12 @@ pushtag (name, type, globalize)
             all function definitions in a translation unit in a convenient
             way.  (It's otherwise tricky to find a member function definition
             it's only pointed to from within a local class.)  */
-         if (TYPE_CONTEXT (type) 
+         if (TYPE_CONTEXT (type)
              && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL
              && !processing_template_decl)
            VARRAY_PUSH_TREE (local_classes, type);
 
-         if (!uses_template_parms (type)) 
+         if (!uses_template_parms (type))
            {
              if (flag_new_abi)
                DECL_ASSEMBLER_NAME (d) = mangle_type (type);
@@ -3850,8 +3815,9 @@ pushdecl (x)
          /* Or in the innermost namespace.  */
          if (! t)
            t = namespace_binding (name, DECL_CONTEXT (x));
-         /* Does it have linkage?  */
-         if (t && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
+         /* Does it have linkage?  Note that if this isn't a DECL, it's an
+            OVERLOAD, which is OK.  */
+         if (t && DECL_P (t) && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
            t = NULL_TREE;
          if (t)
            different_binding_level = 1;
@@ -4048,7 +4014,7 @@ pushdecl (x)
             warn if we later see static one.  */
          if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
            TREE_PUBLIC (name) = 1;
-         
+
          /* Bind the mangled name for the entity.  In the future, we
             should not need to do this; mangled names are an
             implementation detail of which the front-end should not
@@ -4744,7 +4710,7 @@ redeclaration_error_message (newdecl, olddecl)
   else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
     {
       if ((TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
-          && (DECL_TEMPLATE_RESULT (newdecl) 
+          && (DECL_TEMPLATE_RESULT (newdecl)
               != DECL_TEMPLATE_RESULT (olddecl))
           && DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl))
           && DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)))
@@ -5097,14 +5063,16 @@ define_label (filename, line, name)
 {
   tree decl = lookup_label (name);
   struct named_label_list *ent;
+  register struct binding_level *p;
 
   for (ent = named_labels; ent; ent = ent->next)
     if (ent->label_decl == decl)
       break;
 
-  /* After labels, make any new cleanups go into their
+  /* After labels, make any new cleanups in the function go into their
      own new (temporary) binding contour.  */
-  current_binding_level->more_cleanups_ok = 0;
+  for (p = current_binding_level; !(p->parm_flag); p = p->level_chain)
+    p->more_cleanups_ok = 0;
 
   if (name == get_identifier ("wchar_t"))
     cp_pedwarn ("label named wchar_t");
@@ -5151,7 +5119,7 @@ struct cp_switch
    mark the stack for garbage collection because it is only active
    during the processing of the body of a function, and we never
    collect at that point.  */
-   
+
 static struct cp_switch *switch_stack;
 
 /* Called right after a switch-statement condition is parsed.
@@ -5174,7 +5142,7 @@ void
 pop_switch ()
 {
   struct cp_switch *cs;
-  
+
   cs = switch_stack;
   splay_tree_delete (cs->cases);
   switch_stack = switch_stack->next;
@@ -5184,23 +5152,24 @@ pop_switch ()
 /* Note that we've seen a definition of a case label, and complain if this
    is a bad place for one.  */
 
-void
+tree
 finish_case_label (low_value, high_value)
      tree low_value;
      tree high_value;
 {
-  tree cond;
+  tree cond, r;
+  register struct binding_level *p;
 
   if (! switch_stack)
     {
       if (high_value)
        error ("case label not within a switch statement");
       else if (low_value)
-       cp_error ("case label `%E' not within a switch statement", 
+       cp_error ("case label `%E' not within a switch statement",
                  low_value);
       else
        error ("`default' label not within a switch statement");
-      return;
+      return NULL_TREE;
     }
 
   if (processing_template_decl)
@@ -5210,8 +5179,7 @@ finish_case_label (low_value, high_value)
       /* For templates, just add the case label; we'll do semantic
         analysis at instantiation-time.  */
       label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
-      add_stmt (build_case_label (low_value, high_value, label));
-      return;
+      return add_stmt (build_case_label (low_value, high_value, label));
     }
 
   /* Find the condition on which this switch statement depends.  */
@@ -5219,14 +5187,19 @@ finish_case_label (low_value, high_value)
   if (cond && TREE_CODE (cond) == TREE_LIST)
     cond = TREE_VALUE (cond);
 
-  c_add_case_label (switch_stack->cases, cond, low_value, high_value);
+  r = c_add_case_label (switch_stack->cases, cond, low_value, high_value);
+  if (r == error_mark_node)
+    r = NULL_TREE;
 
   check_switch_goto (switch_stack->level);
 
-  /* After labels, make any new cleanups go into their
+  /* After labels, make any new cleanups in the function go into their
      own new (temporary) binding contour.  */
-  current_binding_level->more_cleanups_ok = 0;
+  for (p = current_binding_level; !(p->parm_flag); p = p->level_chain)
+    p->more_cleanups_ok = 0;
   current_function_return_value = NULL_TREE;
+
+  return r;
 }
 \f
 /* Return the list of declarations of the current level.
@@ -5697,8 +5670,8 @@ select_decl (binding, flags)
   /* When we implicitly declare some builtin entity, we mark it
      DECL_ANTICIPATED, so that we know to ignore it until it is
      really declared.  */
-  if (val && DECL_P (val) 
-      && DECL_LANG_SPECIFIC (val) 
+  if (val && DECL_P (val)
+      && DECL_LANG_SPECIFIC (val)
       && DECL_ANTICIPATED (val))
     return NULL_TREE;
 
@@ -5946,7 +5919,10 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
       if (got_scope)
        goto done;
       else if (got_object && val)
-       from_obj = val;
+       {
+         from_obj = val;
+         val = NULL_TREE;
+       }
     }
   else
     {
@@ -6015,13 +5991,12 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
        {
          if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL
              && TREE_CODE (val) == TYPE_DECL
-             && TREE_TYPE (from_obj) != TREE_TYPE (val))
-           {
-             cp_pedwarn ("lookup of `%D' in the scope of `%#T' (`%#T')",
-                         name, got_object, TREE_TYPE (from_obj));
-             cp_pedwarn ("  does not match lookup in the current scope (`%#T')",
-                         TREE_TYPE (val));
-           }
+             && ! same_type_p (TREE_TYPE (from_obj), TREE_TYPE (val)))
+           cp_pedwarn ("\
+lookup of `%D' in the scope of `%#T' (`%#T') \
+does not match lookup in the current scope (`%#T')",
+                       name, got_object, TREE_TYPE (from_obj),
+                       TREE_TYPE (val));
 
          /* We don't change val to from_obj if got_object depends on
             template parms because that breaks implicit typename for
@@ -6264,7 +6239,7 @@ typedef struct predefined_identifier
 /* Create all the predefined identifiers.  */
 
 static void
-initialize_predefined_identifiers () 
+initialize_predefined_identifiers ()
 {
   struct predefined_identifier *pid;
 
@@ -6328,6 +6303,7 @@ init_decl_processing ()
   free_lang_status = &pop_cp_function_context;
   mark_lang_status = &mark_cp_function_context;
   lang_safe_from_p = &c_safe_from_p;
+  lang_dump_tree = &cp_dump_tree;
 
   cp_parse_init ();
   init_decl2 ();
@@ -6382,7 +6358,7 @@ init_decl_processing ()
                                  void_type_node);
       pushdecl (fake_std_node);
     }
-  
+
   /* Define `int' and `char' first so that dbx will output them first.  */
   record_builtin_type (RID_INT, NULL_PTR, integer_type_node);
   record_builtin_type (RID_CHAR, "char", char_type_node);
@@ -6402,14 +6378,10 @@ init_decl_processing ()
                       long_long_unsigned_type_node);
   record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
   record_builtin_type (RID_MAX, "short unsigned int",
-                      short_unsigned_type_node); 
+                      short_unsigned_type_node);
   record_builtin_type (RID_MAX, "unsigned short",
                       short_unsigned_type_node);
 
-  ptrdiff_type_node
-    = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
-  unsigned_ptrdiff_type_node = unsigned_type (ptrdiff_type_node);
-
   /* Define both `signed char' and `unsigned char'.  */
   record_builtin_type (RID_MAX, "signed char", signed_char_type_node);
   record_builtin_type (RID_MAX, "unsigned char", unsigned_char_type_node);
@@ -6494,15 +6466,7 @@ init_decl_processing ()
   void_list_node = build_tree_list (NULL_TREE, void_type_node);
   TREE_PARMLIST (void_list_node) = 1;
 
-  string_type_node = build_pointer_type (char_type_node);
-  const_string_type_node
-    = build_pointer_type (build_qualified_type (char_type_node,
-                                               TYPE_QUAL_CONST));
   empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
-#if 0
-  record_builtin_type (RID_MAX, NULL_PTR, string_type_node);
-#endif
-
   /* Make a type to be the domain of a few array types
      whose domains don't really matter.
      200 is small enough that it always fits in size_t.  */
@@ -6518,6 +6482,12 @@ init_decl_processing ()
   int_array_type_node
     = build_array_type (integer_type_node, array_domain_type);
 
+  c_common_nodes_and_builtins ();
+
+#if 0
+  record_builtin_type (RID_MAX, NULL_PTR, string_type_node);
+#endif
+
   if (flag_new_abi)
     delta_type_node = ptrdiff_type_node;
   else if (flag_huge_objects)
@@ -6530,20 +6500,16 @@ init_decl_processing ()
   else
     vtable_index_type = delta_type_node;
 
-  default_function_type
-    = build_function_type (integer_type_node, NULL_TREE);
-
-  ptr_type_node = build_pointer_type (void_type_node);
-  const_ptr_type_node
-    = build_pointer_type (build_qualified_type (void_type_node,
-                                               TYPE_QUAL_CONST));
   vtt_parm_type = build_pointer_type (const_ptr_type_node);
-  c_common_nodes_and_builtins ();
   lang_type_promotes_to = convert_type_from_ellipsis;
 
   void_ftype_ptr
     = build_exception_variant (void_ftype_ptr, empty_except_spec);
 
+#ifdef MD_INIT_BUILTINS
+  MD_INIT_BUILTINS;
+#endif
+
   /* C++ extensions */
 
   unknown_type_node = make_node (UNKNOWN_TYPE);
@@ -6569,25 +6535,12 @@ init_decl_processing ()
     wchar_type_node = make_signed_type (wchar_type_size);
   else
     wchar_type_node = make_unsigned_type (wchar_type_size);
-  record_builtin_type (RID_WCHAR, "__wchar_t", wchar_type_node);
-
-  /* Artificial declaration of wchar_t -- can be bashed */
-  wchar_decl_node = build_decl (TYPE_DECL, get_identifier ("wchar_t"),
-                               wchar_type_node);
-  pushdecl (wchar_decl_node);
+  record_builtin_type (RID_WCHAR, "wchar_t", wchar_type_node);
 
   /* This is for wide string constants.  */
   wchar_array_type_node
     = build_array_type (wchar_type_node, array_domain_type);
 
-  wint_type_node =
-    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WINT_TYPE)));
-
-  intmax_type_node =
-    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (INTMAX_TYPE)));
-  uintmax_type_node =
-    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (UINTMAX_TYPE)));
-
   if (flag_vtable_thunks)
     {
       /* Make sure we get a unique function type, so we can give
@@ -6665,7 +6618,10 @@ init_decl_processing ()
   }
 
   abort_fndecl
-    = build_library_fn_ptr ("__pure_virtual", void_ftype);
+    = build_library_fn_ptr ((flag_new_abi 
+                            ? "__cxa_pure_virtual"
+                            : "__pure_virtual"),
+                           void_ftype);
 
   /* Perform other language dependent initializations.  */
   init_class_processing ();
@@ -6753,7 +6709,7 @@ cp_make_fname_decl (id, name, type_dep)
   tree decl, type, init;
   size_t length = strlen (name);
   tree domain = NULL_TREE;
-  
+
   if (!processing_template_decl)
     type_dep = 0;
   if (!type_dep)
@@ -6784,7 +6740,7 @@ cp_make_fname_decl (id, name, type_dep)
     }
   DECL_INITIAL (decl) = init;
   cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
-  
+
   /* We will have to make sure we only emit this, if it is actually used. */
   return decl;
 }
@@ -6816,7 +6772,7 @@ builtin_function (name, type, code, class, libname)
 
   /* All builtins that don't begin with an `_' should go in the `std'
      namespace.  */
-  if (flag_honor_std && name[0] != '_') 
+  if (flag_honor_std && name[0] != '_')
     {
       push_namespace (std_identifier);
       DECL_CONTEXT (decl) = std_node;
@@ -6930,7 +6886,7 @@ push_cp_library_fn (operator_code, type)
      enum tree_code operator_code;
      tree type;
 {
-  tree fn = build_cp_library_fn (ansi_opname (operator_code), 
+  tree fn = build_cp_library_fn (ansi_opname (operator_code),
                                 operator_code,
                                 type);
   pushdecl (fn);
@@ -7392,7 +7348,7 @@ start_decl_1 (decl)
       && TREE_CODE (decl) != TYPE_DECL
       && TREE_CODE (decl) != TEMPLATE_DECL
       && type != error_mark_node
-      && IS_AGGR_TYPE (type) 
+      && IS_AGGR_TYPE (type)
       && ! DECL_EXTERNAL (decl))
     {
       if ((! processing_template_decl || ! uses_template_parms (type))
@@ -7652,6 +7608,7 @@ maybe_commonize_var (decl)
         inlining of such functions.  */
       current_function_cannot_inline
        = "function with static variable cannot be inline";
+      DECL_UNINLINABLE (current_function_decl) = 1;
 
       /* If flag_weak, we don't need to mess with this, as we can just
         make the function weak, and let it refer to its unique local
@@ -7915,7 +7872,7 @@ maybe_inject_for_scope_var (decl)
 {
   if (!DECL_NAME (decl))
     return;
-  
+
   if (current_binding_level->is_for_scope)
     {
       struct binding_level *outer
@@ -7993,7 +7950,7 @@ initialize_local_var (decl, init, flags)
          saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
          current_stmt_tree ()->stmts_are_full_exprs_p = 1;
          finish_expr_stmt (build_aggr_init (decl, init, flags));
-         current_stmt_tree ()->stmts_are_full_exprs_p = 
+         current_stmt_tree ()->stmts_are_full_exprs_p =
            saved_stmts_are_full_exprs_p;
        }
 
@@ -8107,9 +8064,9 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
 
   if (type == error_mark_node)
     return;
-  
+
   /* Add this declaration to the statement-tree.  */
-  if (building_stmt_tree () 
+  if (building_stmt_tree ()
       && at_function_scope_p ()
       && TREE_CODE (decl) != RESULT_DECL)
     add_decl_stmt (decl);
@@ -8949,6 +8906,9 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
           orig_declarator);
       else
        {
+         tree fns = TREE_OPERAND (orig_declarator, 0);
+         tree args = TREE_OPERAND (orig_declarator, 1);
+         
          if (PROCESSING_REAL_TEMPLATE_DECL_P ())
            {
              /* Something like `template <class T> friend void f<T>()'.  */
@@ -8961,10 +8921,22 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
          /* 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)
-           = tree_cons (TREE_OPERAND (orig_declarator, 0),
-                        TREE_OPERAND (orig_declarator, 1),
-                        NULL_TREE);
+
+          if (TREE_CODE (fns) == COMPONENT_REF)
+            {
+              /* Due to bison parser ickiness, we will have already looked
+                 up an operator_name or PFUNCNAME within the current class
+                 (see template_id in parse.y). If the current class contains
+                 such a name, we'll get a COMPONENT_REF here. Undo that. */
+              
+              my_friendly_assert (TREE_TYPE (TREE_OPERAND (fns, 0))
+                                  == current_class_type, 20001120);
+              fns = TREE_OPERAND (fns, 1);
+            }
+         my_friendly_assert (TREE_CODE (fns) == IDENTIFIER_NODE
+                             || TREE_CODE (fns) == LOOKUP_EXPR
+                             || TREE_CODE (fns) == OVERLOAD, 20001120);
+         DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE);
 
          if (has_default_arg)
            {
@@ -9068,12 +9040,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
     return decl;
 
   if (virtualp)
-    {
-      DECL_VIRTUAL_P (decl) = 1;
-      if (DECL_VINDEX (decl) == NULL_TREE)
-       DECL_VINDEX (decl) = error_mark_node;
-      IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
-    }
+    DECL_VIRTUAL_P (decl) = 1;
 
   return decl;
 }
@@ -9133,12 +9100,12 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
        set_decl_namespace (decl, context, 0);
 
       context = DECL_CONTEXT (decl);
-      if (declarator && context && current_lang_name != lang_name_c) 
+      if (declarator && context && current_lang_name != lang_name_c)
        {
          if (flag_new_abi)
            DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
          else
-           DECL_ASSEMBLER_NAME (decl) 
+           DECL_ASSEMBLER_NAME (decl)
              = build_static_name (context, declarator);
        }
     }
@@ -9208,6 +9175,9 @@ build_ptrmemfunc_type (type)
   tree u;
   tree unqualified_variant = NULL_TREE;
 
+  if (type == error_mark_node)
+    return type;
+  
   /* If a canonical type already exists for this type, use it.  We use
      this method instead of type_hash_canon, because it only does a
      simple equality check on the list of field members.  */
@@ -9540,7 +9510,7 @@ check_special_function_return_type (sfk, type, ctype, optype)
     case sfk_constructor:
       if (type)
        cp_error ("return type specification for constructor invalid");
-       
+
       /* In the old ABI, we return `this'; in the new ABI we don't
         bother.  */
       type = flag_new_abi ? void_type_node : build_pointer_type        (ctype);
@@ -9861,7 +9831,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                ctor_return_type = TREE_TYPE (dname);
                sfk = sfk_conversion;
                if (IDENTIFIER_GLOBAL_VALUE (dname)
-                   && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (dname)) 
+                   && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (dname))
                        == TYPE_DECL))
                  name = IDENTIFIER_POINTER (dname);
                else
@@ -10432,7 +10402,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  if (IDENTIFIER_TYPENAME_P (tmp))
                    {
                      if (IDENTIFIER_GLOBAL_VALUE (tmp)
-                         && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (tmp)) 
+                         && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (tmp))
                              == TYPE_DECL))
                        name = IDENTIFIER_POINTER (tmp);
                      else
@@ -10575,7 +10545,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            type = create_array_type_for_decl (dname, type, size);
 
            /* VLAs never work as fields. */
-           if (decl_context == FIELD && !processing_template_decl 
+           if (decl_context == FIELD && !processing_template_decl
                && TREE_CODE (type) == ARRAY_TYPE
                && TYPE_DOMAIN (type) != NULL_TREE
                && !TREE_CONSTANT (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
@@ -10697,7 +10667,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                      }
                    {
                      RID_BIT_TYPE tmp_bits;
-                     bcopy ((void*)&specbits, (void*)&tmp_bits, sizeof (RID_BIT_TYPE));
+                     memcpy (&tmp_bits, &specbits, sizeof (RID_BIT_TYPE));
                      RIDBIT_RESET (RID_INLINE, tmp_bits);
                      RIDBIT_RESET (RID_STATIC, tmp_bits);
                      if (RIDBIT_ANY_SET (tmp_bits))
@@ -10743,7 +10713,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            /* FIXME: This is where default args should be fully
               processed.  */
 
-           arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0);
+           arg_types = grokparms (inner_parms);
 
            if (declarator && flags == DTOR_FLAG)
              {
@@ -10938,7 +10908,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            t = ctype;
            while (t != NULL_TREE && CLASS_TYPE_P (t))
              {
-               /* You're supposed to have one `template <...>' 
+               /* You're supposed to have one `template <...>'
                   for every template class, but you don't need one
                   for a full specialization.  For example:
 
@@ -10982,8 +10952,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  }
                else if (TREE_CODE (type) == FUNCTION_TYPE)
                  {
-                   if (current_class_type == NULL_TREE
-                       || friendp)
+                   if (current_class_type == NULL_TREE || friendp)
                      type = build_cplus_method_type (ctype, TREE_TYPE (type),
                                                      TYPE_ARG_TYPES (type));
                    else
@@ -11009,18 +10978,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                      }
                    type = build_offset_type (ctype, type);
                  }
-               else if (uses_template_parms (ctype))
-                 {
-                    if (TREE_CODE (type) == FUNCTION_TYPE)
-                     type
-                       = build_cplus_method_type (ctype, TREE_TYPE (type),
-                                                  TYPE_ARG_TYPES (type));
-                 }
                else
-                 {
-                   cp_error ("structure `%T' not yet defined", ctype);
-                   return error_mark_node;
-                 }
+                 {
+                   incomplete_type_error (NULL_TREE, ctype);
+                   return error_mark_node;
+                 }
 
                declarator = sname;
              }
@@ -11181,7 +11143,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
              = TYPE_IDENTIFIER (type);
 
-         if (flag_new_abi) 
+         if (flag_new_abi)
            DECL_ASSEMBLER_NAME (decl) = mangle_type (type);
          else
            {
@@ -11193,7 +11155,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                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));
@@ -11272,7 +11234,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            }
 
          /* Until core issue 180 is resolved, allow 'friend typename A::B'.
-            But don't allow implicit typenames.  */
+            But don't allow implicit typenames except with a class-key.  */
          if (!current_aggr && (TREE_CODE (type) != TYPENAME_TYPE
                                || IMPLICIT_TYPENAME_P (type)))
            {
@@ -11292,12 +11254,15 @@ friend declaration requires class-key, i.e. `friend %#T'",
          /* Only try to do this stuff if we didn't already give up.  */
          if (type != integer_type_node)
            {
+             decl_type_access_control (TYPE_NAME (type));
+             
              /* A friendly class?  */
              if (current_class_type)
                make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type));
              else
                cp_error ("trying to make class `%T' a friend of global scope",
                          type);
+              
              type = void_type_node;
            }
        }
@@ -11372,11 +11337,6 @@ friend declaration requires class-key, i.e. `friend %#T'",
        type = build_pointer_type (type);
       else if (TREE_CODE (type) == OFFSET_TYPE)
        type = build_pointer_type (type);
-      else if (TREE_CODE (type) == VOID_TYPE && declarator)
-       {
-         error ("declaration of `%s' as void", name);
-         return NULL_TREE;
-       }
     }
 
   {
@@ -11842,25 +11802,13 @@ require_complete_types_for_parms (parms)
 {
   for (; parms; parms = TREE_CHAIN (parms))
     {
-      tree type = TREE_TYPE (parms);
-
-      /* Try to complete the TYPE.  */
-      type = complete_type (type);
-
-      if (type == error_mark_node)
-       continue;
-
-      if (!COMPLETE_TYPE_P (type))
-       {
-         if (DECL_NAME (parms))
-           error ("parameter `%s' has incomplete type",
-                  IDENTIFIER_POINTER (DECL_NAME (parms)));
-         else
-           error ("parameter has incomplete type");
-         TREE_TYPE (parms) = error_mark_node;
-       }
-      else
+      if (VOID_TYPE_P (TREE_TYPE (parms)))
+        /* grokparms will have already issued an error */
+        TREE_TYPE (parms) = error_mark_node;
+      else if (complete_type_or_else (TREE_TYPE (parms), parms))
        layout_decl (parms, 0);
+      else
+        TREE_TYPE (parms) = error_mark_node;
     }
 }
 
@@ -11974,7 +11922,7 @@ check_default_argument (decl, arg)
 
      The keyword `this' shall not be used in a default argument of a
      member function.  */
-  var = walk_tree_without_duplicates (&arg, local_variable_p_walkfn, 
+  var = walk_tree_without_duplicates (&arg, local_variable_p_walkfn,
                                      NULL);
   if (var)
     {
@@ -11991,205 +11939,120 @@ check_default_argument (decl, arg)
    Given the list of things declared inside the parens,
    return a list of types.
 
-   The list we receive can have three kinds of elements:
-   an IDENTIFIER_NODE for names given without types,
-   a TREE_LIST node for arguments given as typespecs or names with typespecs,
-   or void_type_node, to mark the end of an argument list
-   when additional arguments are not permitted (... was not used).
-
-   FUNCDEF_FLAG is nonzero for a function definition, 0 for
-   a mere declaration.  A nonempty identifier-list gets an error message
-   when FUNCDEF_FLAG is zero.
-   If FUNCDEF_FLAG is 1, then parameter types must be complete.
-   If FUNCDEF_FLAG is -1, then parameter types may be incomplete.
-
-   If all elements of the input list contain types,
-   we return a list of the types.
-   If all elements contain no type (except perhaps a void_type_node
-   at the end), we return a null list.
-   If some have types and some do not, it is an error, and we
-   return a null list.
-
-   Also set last_function_parms to either
-   a list of names (IDENTIFIER_NODEs) or a chain of PARM_DECLs.
-   A list of names is converted to a chain of PARM_DECLs
-   by store_parm_decls so that ultimately it is always a chain of decls.
-
-   Note that in C++, parameters can take default values.  These default
-   values are in the TREE_PURPOSE field of the TREE_LIST.  It is
-   an error to specify default values which are followed by parameters
-   that have no default values, or an ELLIPSES.  For simplicities sake,
-   only parameters which are specified with their types can take on
-   default values.  */
+   We determine whether ellipsis parms are used by PARMLIST_ELLIPSIS_P
+   flag. If unset, we append void_list_node. A parmlist declared
+   as `(void)' is accepted as the empty parmlist.
+
+   Also set last_function_parms to the chain of PARM_DECLs.  */
 
 static tree
-grokparms (first_parm, funcdef_flag)
+grokparms (first_parm)
      tree first_parm;
-     int funcdef_flag;
 {
   tree result = NULL_TREE;
   tree decls = NULL_TREE;
+  int ellipsis = !first_parm || PARMLIST_ELLIPSIS_P (first_parm);
+  tree parm, chain;
+  int any_error = 0;
 
-  if (first_parm != NULL_TREE
-      && TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE)
-    {
-      if (! funcdef_flag)
-       pedwarn ("parameter names (without types) in function declaration");
-      last_function_parms = first_parm;
-      return NULL_TREE;
-    }
-  else if (first_parm != NULL_TREE
-          && TREE_CODE (TREE_VALUE (first_parm)) != TREE_LIST
-          && TREE_CODE (TREE_VALUE (first_parm)) != VOID_TYPE)
-    my_friendly_abort (145);
-  else
-    {
-      /* Types were specified.  This is a list of declarators
-        each represented as a TREE_LIST node.  */
-      register tree parm, chain;
-      int any_init = 0, any_error = 0;
+  my_friendly_assert (!first_parm || TREE_PARMLIST (first_parm), 20001115);
 
-      if (first_parm != NULL_TREE)
-       {
-         tree last_result = NULL_TREE;
-         tree last_decl = NULL_TREE;
-
-         for (parm = first_parm; parm != NULL_TREE; parm = chain)
-           {
-             tree type = NULL_TREE, list_node = parm;
-             register tree decl = TREE_VALUE (parm);
-             tree init = TREE_PURPOSE (parm);
-
-             chain = TREE_CHAIN (parm);
-             /* @@ weak defense against parse errors.  */
-             if (TREE_CODE (decl) != VOID_TYPE
-                 && TREE_CODE (decl) != TREE_LIST)
-               {
-                 /* Give various messages as the need arises.  */
-                 if (TREE_CODE (decl) == STRING_CST)
-                   cp_error ("invalid string constant `%E'", decl);
-                 else if (TREE_CODE (decl) == INTEGER_CST)
-                   error ("invalid integer constant in parameter list, did you forget to give parameter name?");
-                 continue;
-               }
-
-             if (TREE_CODE (decl) != VOID_TYPE)
-               {
-                 decl = grokdeclarator (TREE_VALUE (decl),
-                                        TREE_PURPOSE (decl),
-                                        PARM, init != NULL_TREE,
-                                        NULL_TREE);
-                 if (! decl || TREE_TYPE (decl) == error_mark_node)
-                   continue;
-
-                 /* Top-level qualifiers on the parameters are
-                    ignored for function types.  */
-                 type = TYPE_MAIN_VARIANT (TREE_TYPE (decl));
-
-                 if (TREE_CODE (type) == VOID_TYPE)
-                   decl = void_type_node;
-                 else if (TREE_CODE (type) == METHOD_TYPE)
-                   {
-                     if (DECL_NAME (decl))
-                       /* Cannot use the decl here because
-                          we don't have DECL_CONTEXT set up yet.  */
-                       cp_error ("parameter `%D' invalidly declared method type",
-                                 DECL_NAME (decl));
-                     else
-                       error ("parameter invalidly declared method type");
-                     type = build_pointer_type (type);
-                     TREE_TYPE (decl) = type;
-                   }
-                 else if (TREE_CODE (type) == OFFSET_TYPE)
-                   {
-                     if (DECL_NAME (decl))
-                       cp_error ("parameter `%D' invalidly declared offset type",
-                                 DECL_NAME (decl));
-                     else
-                       error ("parameter invalidly declared offset type");
-                     type = build_pointer_type (type);
-                     TREE_TYPE (decl) = type;
-                   }
-                  else if (abstract_virtuals_error (decl, type))
-                   any_error = 1;  /* Seems like a good idea. */
-                 else if (POINTER_TYPE_P (type))
-                   {
-                     tree t = type;
-                     while (POINTER_TYPE_P (t)
-                            || (TREE_CODE (t) == ARRAY_TYPE
-                                && TYPE_DOMAIN (t) != NULL_TREE))
-                       t = TREE_TYPE (t);
-                     if (TREE_CODE (t) == ARRAY_TYPE)
-                       cp_error ("parameter type `%T' includes %s to array of unknown bound",
-                                 type,
-                                 TYPE_PTR_P (type) ? "pointer" : "reference");
-                   }
-               }
+  for (parm = first_parm; parm != NULL_TREE; parm = chain)
+    {
+      tree type = NULL_TREE;
+      register tree decl = TREE_VALUE (parm);
+      tree init = TREE_PURPOSE (parm);
+
+      chain = TREE_CHAIN (parm);
+      /* @@ weak defense against parse errors.  */
+      if (TREE_CODE (decl) != VOID_TYPE
+         && TREE_CODE (decl) != TREE_LIST)
+       {
+         /* Give various messages as the need arises.  */
+         if (TREE_CODE (decl) == STRING_CST)
+           cp_error ("invalid string constant `%E'", decl);
+         else if (TREE_CODE (decl) == INTEGER_CST)
+           error ("invalid integer constant in parameter list, did you forget to give parameter name?");
+         continue;
+       }
 
-             if (TREE_CODE (decl) == VOID_TYPE)
-               {
-                 if (result == NULL_TREE)
-                   {
-                     result = void_list_node;
-                     last_result = result;
-                   }
-                 else
-                   {
-                     TREE_CHAIN (last_result) = void_list_node;
-                     last_result = void_list_node;
-                   }
-                 if (chain
-                     && (chain != void_list_node || TREE_CHAIN (chain)))
-                   error ("`void' in parameter list must be entire list");
-                 break;
-               }
+      if (parm == void_list_node)
+        break;
 
-             /* Since there is a prototype, args are passed in their own types.  */
-             DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
-             if (PROMOTE_PROTOTYPES
-                 && (TREE_CODE (type) == INTEGER_TYPE
-                     || TREE_CODE (type) == ENUMERAL_TYPE)
-                 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
-               DECL_ARG_TYPE (decl) = integer_type_node;
-             if (!any_error && init)
-               {
-                 any_init++;
-                 init = check_default_argument (decl, init);
-               }
-             else
-               init = NULL_TREE;
+      decl = grokdeclarator (TREE_VALUE (decl), TREE_PURPOSE (decl),
+                            PARM, init != NULL_TREE, NULL_TREE);
+      if (! decl || TREE_TYPE (decl) == error_mark_node)
+        continue;
+    
+      type = TREE_TYPE (decl);
+      if (VOID_TYPE_P (type))
+        {
+          if (same_type_p (type, void_type_node)
+              && !DECL_NAME (decl) && !result && !chain && !ellipsis)
+            /* this is a parmlist of `(void)', which is ok.  */
+            break;
+          incomplete_type_error (decl, type);
+         /* It's not a good idea to actually create parameters of
+            type `void'; other parts of the compiler assume that a
+            void type terminates the parameter list.  */
+         type = error_mark_node;
+         TREE_TYPE (decl) = error_mark_node;
+        }
 
-             if (decls == NULL_TREE)
-               {
-                 decls = decl;
-                 last_decl = decls;
-               }
-             else
-               {
-                 TREE_CHAIN (last_decl) = decl;
-                 last_decl = decl;
-               }
-             list_node = tree_cons (init, type, NULL_TREE);
-             if (result == NULL_TREE)
-               {
-                 result = list_node;
-                 last_result = result;
-               }
-             else
-               {
-                 TREE_CHAIN (last_result) = list_node;
-                 last_result = list_node;
-               }
+      if (type != error_mark_node) 
+       {
+         /* Top-level qualifiers on the parameters are
+            ignored for function types.  */
+         type = TYPE_MAIN_VARIANT (type);
+         if (TREE_CODE (type) == METHOD_TYPE)
+           {
+             cp_error ("parameter `%D' invalidly declared method type", decl);
+             type = build_pointer_type (type);
+             TREE_TYPE (decl) = type;
+           }
+         else if (TREE_CODE (type) == OFFSET_TYPE)
+           {
+             cp_error ("parameter `%D' invalidly declared offset type", decl);
+             type = build_pointer_type (type);
+             TREE_TYPE (decl) = type;
            }
-         if (last_result)
-           TREE_CHAIN (last_result) = NULL_TREE;
-         /* If there are no parameters, and the function does not end
-            with `...', then last_decl will be NULL_TREE.  */
-         if (last_decl != NULL_TREE)
-           TREE_CHAIN (last_decl) = NULL_TREE;
+         else if (abstract_virtuals_error (decl, type))
+           any_error = 1;  /* Seems like a good idea. */
+         else if (POINTER_TYPE_P (type))
+           {
+             /* [dcl.fct]/6, parameter types cannot contain pointers
+                (references) to arrays of unknown bound.  */
+             tree t = type;
+
+             while (POINTER_TYPE_P (t)
+                    || (TREE_CODE (t) == ARRAY_TYPE
+                        && TYPE_DOMAIN (t) != NULL_TREE))
+               t = TREE_TYPE (t);
+             if (TREE_CODE (t) == ARRAY_TYPE)
+               cp_error ("parameter `%D' includes %s to array of unknown bound `%T'",
+                         decl, TYPE_PTR_P (type) ? "pointer" : "reference", t);
+           }
+
+         DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
+         if (PROMOTE_PROTOTYPES
+             && (TREE_CODE (type) == INTEGER_TYPE
+                 || TREE_CODE (type) == ENUMERAL_TYPE)
+             && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+           DECL_ARG_TYPE (decl) = integer_type_node;
+         if (!any_error && init)
+           init = check_default_argument (decl, init);
+         else
+           init = NULL_TREE;
        }
-    }
 
+      TREE_CHAIN (decl) = decls;
+      decls = decl;
+      result = tree_cons (init, type, result);
+    }
+  decls = nreverse (decls);
+  result = nreverse (result);
+  if (!ellipsis)
+    result = chainon (result, void_list_node);
   last_function_parms = decls;
 
   return result;
@@ -12272,9 +12135,7 @@ grok_ctor_properties (ctype, decl)
      other parameters have default arguments.  */
   if (TREE_CODE (parmtype) == REFERENCE_TYPE
       && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == ctype
-      && (TREE_CHAIN (parmtypes) == NULL_TREE
-         || TREE_CHAIN (parmtypes) == void_list_node
-         || TREE_PURPOSE (TREE_CHAIN (parmtypes)))
+      && sufficient_parms_p (TREE_CHAIN (parmtypes))
       && !(DECL_TEMPLATE_INSTANTIATION (decl)
           && is_member_template (DECL_TI_TEMPLATE (decl))))
     {
@@ -12298,9 +12159,7 @@ grok_ctor_properties (ctype, decl)
      existence.  Theoretically, they should never even be
      instantiated, but that's hard to forestall.  */
   else if (TYPE_MAIN_VARIANT (parmtype) == ctype
-          && (TREE_CHAIN (parmtypes) == NULL_TREE
-              || TREE_CHAIN (parmtypes) == void_list_node
-              || TREE_PURPOSE (TREE_CHAIN (parmtypes)))
+          && sufficient_parms_p (TREE_CHAIN (parmtypes))
           && !(DECL_TEMPLATE_INSTANTIATION (decl)
                && is_member_template (DECL_TI_TEMPLATE (decl))))
     {
@@ -12399,7 +12258,7 @@ grok_op_properties (decl, virtualp, friendp)
        case CALL_EXPR:
          TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1;
          break;
-         
+
        case ARRAY_REF:
          TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1;
          break;
@@ -12408,19 +12267,19 @@ grok_op_properties (decl, virtualp, friendp)
        case MEMBER_REF:
          TYPE_OVERLOADS_ARROW (current_class_type) = 1;
          break;
-         
+
        case NEW_EXPR:
          TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
          break;
-         
+
        case DELETE_EXPR:
          TYPE_GETS_DELETE (current_class_type) |= 1;
          break;
-         
+
        case VEC_NEW_EXPR:
          TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1;
          break;
-         
+
        case VEC_DELETE_EXPR:
          TYPE_GETS_DELETE (current_class_type) |= 2;
          break;
@@ -12437,27 +12296,14 @@ grok_op_properties (decl, virtualp, friendp)
       if (methodp)
        revert_static_member_fn (decl);
 
-      /* Take care of function decl if we had syntax errors.  */
-      if (argtypes == NULL_TREE)
-       TREE_TYPE (decl)
-         = build_function_type (ptr_type_node,
-                                hash_tree_chain (integer_type_node,
-                                                 void_list_node));
-      else
-       TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
+      TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
     }
   else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
     {
       if (methodp)
        revert_static_member_fn (decl);
 
-      if (argtypes == NULL_TREE)
-       TREE_TYPE (decl)
-         = build_function_type (void_type_node,
-                                hash_tree_chain (ptr_type_node,
-                                                 void_list_node));
-      else
-       TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
+      TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
     }
   else
     {
@@ -12511,7 +12357,7 @@ grok_op_properties (decl, virtualp, friendp)
            {
              int ref = (TREE_CODE (t) == REFERENCE_TYPE);
              const char *what = 0;
-             
+
              if (ref)
                t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
 
@@ -12531,7 +12377,7 @@ grok_op_properties (decl, virtualp, friendp)
            }
        }
 
-      if (DECL_ASSIGNMENT_OPERATOR_P (decl) 
+      if (DECL_ASSIGNMENT_OPERATOR_P (decl)
          && operator_code == NOP_EXPR)
        {
          tree parmtype;
@@ -13131,9 +12977,9 @@ xref_basetypes (code_type_node, name, ref, binfo)
 
          if (CLASS_TYPE_P (basetype))
            {
-             TYPE_HAS_NEW_OPERATOR (ref) 
+             TYPE_HAS_NEW_OPERATOR (ref)
                |= TYPE_HAS_NEW_OPERATOR (basetype);
-             TYPE_HAS_ARRAY_NEW_OPERATOR (ref) 
+             TYPE_HAS_ARRAY_NEW_OPERATOR (ref)
                |= TYPE_HAS_ARRAY_NEW_OPERATOR (basetype);
              TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
              /* If the base-class uses multiple inheritance, so do we.  */
@@ -13719,7 +13565,8 @@ start_function (declspecs, declarator, attrs, flags)
   /* Initialize RTL machinery.  We cannot do this until
      CURRENT_FUNCTION_DECL and DECL_RESULT are set up.  We do this
      even when processing a template; this is how we get
-     CFUN set up, and our per-function variables initialized.  */
+     CFUN set up, and our per-function variables initialized.
+     FIXME factor out the non-RTL stuff.  */
   bl = current_binding_level;
   init_function_start (decl1, input_filename, lineno);
   current_binding_level = bl;
@@ -13763,7 +13610,7 @@ start_function (declspecs, declarator, attrs, flags)
 
   /* If we are (erroneously) defining a function that we have already
      defined before, wipe out what we knew before.  */
-  if (!DECL_PENDING_INLINE_P (decl1) 
+  if (!DECL_PENDING_INLINE_P (decl1)
       && DECL_SAVED_FUNCTION_DATA (decl1))
     {
       free (DECL_SAVED_FUNCTION_DATA (decl1));
@@ -13963,7 +13810,7 @@ store_parm_decls (current_function_parms)
              else
                cp_error ("parameter `%D' declared void", parm);
 
-             cleanup = (processing_template_decl 
+             cleanup = (processing_template_decl
                         ? NULL_TREE
                         : maybe_build_cleanup (parm));
 
@@ -14035,8 +13882,7 @@ save_function_data (decl)
   /* Make a copy.  */
   f = ((struct cp_language_function *)
        xmalloc (sizeof (struct cp_language_function)));
-  bcopy ((char *) cp_function_chain, (char *) f,
-        sizeof (struct cp_language_function));
+  memcpy (f, cp_function_chain, sizeof (struct cp_language_function));
   DECL_SAVED_FUNCTION_DATA (decl) = f;
 
   /* Clear out the bits we don't need.  */
@@ -14612,7 +14458,7 @@ revert_static_member_fn (decl)
   if (CP_TYPE_QUALS (TREE_TYPE (TREE_VALUE (args)))
       != TYPE_UNQUALIFIED)
     cp_error ("static member function `%#D' declared with type qualifiers",
-             *decl);
+             decl);
 
   args = TREE_CHAIN (args);
   tmp = build_function_type (TREE_TYPE (function), args);
@@ -14729,7 +14575,7 @@ lang_mark_tree (t)
        {
          ggc_mark (ld);
          c_mark_lang_decl (&ld->decl_flags.base);
-         if (!DECL_GLOBAL_CTOR_P (t) 
+         if (!DECL_GLOBAL_CTOR_P (t)
              && !DECL_GLOBAL_DTOR_P (t)
              && !DECL_THUNK_P (t))
            ggc_mark_tree (ld->decl_flags.u2.access);
@@ -14780,3 +14626,13 @@ lang_mark_tree (t)
        ggc_mark_tree ((tree) lt);
     }
 }
+
+/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
+   the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
+
+tree
+identifier_global_value        (t)
+     tree t;
+{
+  return IDENTIFIER_GLOBAL_VALUE (t);
+}