OSDN Git Service

* c-common.c (decl_attributes): Only take a single attributes
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl2.c
index 51b734f..e6d4274 100644 (file)
@@ -45,6 +45,7 @@ Boston, MA 02111-1307, USA.  */
 #include "ggc.h"
 #include "timevar.h"
 #include "cpplib.h"
+#include "target.h"
 extern cpp_reader *parse_in;
 
 /* This structure contains information about the initializations
@@ -92,11 +93,6 @@ static tree key_method PARAMS ((tree));
 static int compare_options PARAMS ((const PTR, const PTR));
 static tree get_guard_bits PARAMS ((tree));
 
-extern int current_class_depth;
-
-/* A list of virtual function tables we must make sure to write out.  */
-tree pending_vtables;
-
 /* A list of static class variables.  This is needed, because a
    static class variable can be declared inside the class without
    an initializer, and then initialized, staticly, outside the class.  */
@@ -130,11 +126,6 @@ tree static_dtors;
 /* The :: namespace. */
 
 tree global_namespace;
-
-/* The stack for namespaces of current declarations. */
-
-static tree decl_namespace_list;
-
 \f
 /* C (and C++) language-specific option variables.  */
 
@@ -283,10 +274,6 @@ int warn_overloaded_virtual;
 
 int warn_nonvdtor;
 
-/* Non-zero means warn when a function is declared extern and later inline.  */
-
-int warn_extern_inline;
-
 /* Non-zero means warn when the compiler will reorder code.  */
 
 int warn_reorder;
@@ -337,10 +324,6 @@ int warn_deprecated = 1;
 #endif
 int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
 
-/* Nonzero means that labels can be used as first-class objects */
-
-int flag_labels_ok;
-
 /* Nonzero means allow Microsoft extensions without a pedwarn.  */
 
 int flag_ms_extensions;
@@ -361,11 +344,6 @@ int flag_default_inline = 1;
 
 int flag_rtti = 1;
 
-/* Nonzero if we wish to output cross-referencing information
-   for the GNU class browser.  */
-
-extern int flag_gnu_xref;
-
 /* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
    objects.  */
 
@@ -391,10 +369,6 @@ int flag_operator_names = 1;
 
 int flag_check_new;
 
-/* Nonnull if we want to dump class heirarchies.  */
-
-const char *flag_dump_class_layout;
-
 /* Nonzero if we want the new ISO rules for pushing a new scope for `for'
    initialization variables.
    0: Old rules, set by -fno-for-scope.
@@ -417,10 +391,12 @@ int flag_use_cxa_atexit;
 
 /* Nonzero to not ignore namespace std. */
 
-int flag_honor_std = ENABLE_STD_NAMESPACE;
+int flag_honor_std = 1;
 
-/* Nonzero if we should expand functions calls inline at the tree
-   level, rather than at the RTL level.  */
+/* 0 if we should not perform inlining.
+   1 if we should expand functions calls inline at the tree level.  
+   2 if we should consider *all* functions to be inline 
+   candidates.  */
 
 int flag_inline_trees = 0;
 
@@ -484,11 +460,9 @@ lang_f_options[] =
   {"gnu-keywords", &flag_no_gnu_keywords, 0},
   {"handle-exceptions", &flag_exceptions, 1},
   {"honor-std", &flag_honor_std, 1},
-  {"huge-objects", &flag_huge_objects, 1},
   {"implement-inlines", &flag_implement_inlines, 1},
   {"implicit-inline-templates", &flag_implicit_inline_templates, 1},
   {"implicit-templates", &flag_implicit_templates, 1},
-  {"labels-ok", &flag_labels_ok, 1},
   {"ms-extensions", &flag_ms_extensions, 1},
   {"nonansi-builtins", &flag_no_nonansi_builtin, 0},
   {"operator-names", &flag_operator_names, 1},
@@ -497,11 +471,9 @@ lang_f_options[] =
   {"repo", &flag_use_repository, 1},
   {"rtti", &flag_rtti, 1},
   {"stats", &flag_detailed_statistics, 1},
-  {"use-cxa-atexit", &flag_use_cxa_atexit, 1},
   {"vtable-gc", &flag_vtable_gc, 1},
-  {"vtable-thunks", &flag_vtable_thunks, 1},
-  {"weak", &flag_weak, 1},
-  {"xref", &flag_gnu_xref, 1}
+  {"use-cxa-atexit", &flag_use_cxa_atexit, 1},
+  {"weak", &flag_weak, 1}
 };
 
 /* The list of `-f' options that we no longer support.  The `-f'
@@ -512,10 +484,15 @@ static const char * const unsupported_options[] = {
   "cond-mismatch",
   "enum-int-equiv",
   "guiding-decls",
+  "huge-objects",
+  "labels-ok",
+  "new-abi",
   "nonnull-objects",
   "squangle",
   "strict-prototype",
   "this-is-variable",
+  "vtable-thunks",
+  "xref"
 };
 
 /* Compare two option strings, pointed two by P1 and P2, for use with
@@ -610,24 +587,8 @@ cxx_decode_option (argc, argv)
          warning ("-fname-mangling-version is no longer supported");
          return 1;
        }
-      else if ((option_value
-                = skip_leading_substring (p, "dump-translation-unit=")))
-       {
-         if (!*option_value)
-           error ("no file specified with -fdump-translation-unit");
-         else
-           flag_dump_translation_unit = option_value;
-       }
-      else if ((option_value
-                = skip_leading_substring (p, "dump-class-layout=")))
-       {
-         if (!*option_value)
-           error ("no file specified with -fdump-class-layout");
-         else
-           flag_dump_class_layout = option_value;
-       }
-      else if (!strcmp (p, "dump-class-layout"))
-       flag_dump_class_layout = ""; /* empty string for stderr */
+      else if (dump_switch_p (p))
+       ;
       else 
        {
          int found = 0;
@@ -716,8 +677,6 @@ cxx_decode_option (argc, argv)
        warn_parentheses = setting;
       else if (!strcmp (p, "non-virtual-dtor"))
        warn_nonvdtor = setting;
-      else if (!strcmp (p, "extern-inline"))
-       warn_extern_inline = setting;
       else if (!strcmp (p, "reorder"))
        warn_reorder = setting;
       else if (!strcmp (p, "synth"))
@@ -1023,7 +982,7 @@ grokclassfn (ctype, function, flags, quals)
 
   /* Even within an `extern "C"' block, members get C++ linkage.  See
      [dcl.link] for details.  */
-  DECL_LANGUAGE (function) = lang_cplusplus;
+  SET_DECL_LANGUAGE (function, lang_cplusplus);
 
   if (fn_name == NULL_TREE)
     {
@@ -1061,17 +1020,17 @@ grokclassfn (ctype, function, flags, quals)
   DECL_ARGUMENTS (function) = last_function_parms;
   DECL_CONTEXT (function) = ctype;
 
+  if (flags == DTOR_FLAG)
+    DECL_DESTRUCTOR_P (function) = 1;
+
   if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))
     maybe_retrofit_in_chrg (function);
 
   if (flags == DTOR_FLAG)
     {
       DECL_DESTRUCTOR_P (function) = 1;
-      set_mangled_name_for_decl (function);
       TYPE_HAS_DESTRUCTOR (ctype) = 1;
     }
-  else
-    set_mangled_name_for_decl (function);
 }
 
 /* Work on the expr used by alignof (this is only called by the parser).  */
@@ -1436,22 +1395,6 @@ check_classfn (ctype, function)
                   fndecls = OVL_NEXT (fndecls))
                {
                  fndecl = OVL_CURRENT (fndecls);
-                 /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL, or
-                    for a for member function of a template class, is
-                    not mangled, so the check below does not work
-                    correctly in that case.  Since mangled destructor
-                    names do not include the type of the arguments,
-                    we can't use this short-cut for them, either.
-                    (It's not legal to declare arguments for a
-                    destructor, but some people try.)  */
-                 if (!DECL_DESTRUCTOR_P (function)
-                     && (DECL_ASSEMBLER_NAME (function)
-                         != DECL_NAME (function))
-                     && (DECL_ASSEMBLER_NAME (fndecl)
-                         != DECL_NAME (fndecl))
-                     && (DECL_ASSEMBLER_NAME (function) 
-                         == DECL_ASSEMBLER_NAME (fndecl)))
-                   return fndecl;
 
                  /* We cannot simply call decls_match because this
                     doesn't work for static member functions that are 
@@ -1525,24 +1468,17 @@ finish_static_data_member_decl (decl, init, asmspec_tree, flags)
      tree asmspec_tree;
      int flags;
 {
-  const char *asmspec = 0;
-
-  if (asmspec_tree)
-    asmspec = TREE_STRING_POINTER (asmspec_tree);
-
   my_friendly_assert (TREE_PUBLIC (decl), 0);
 
   DECL_CONTEXT (decl) = current_class_type;
 
   /* We cannot call pushdecl here, because that would fill in the
-     decl of our TREE_CHAIN.  Instead, we modify cp_finish_decl to do
+     TREE_CHAIN of our decl.  Instead, we modify cp_finish_decl to do
      the right thing, namely, to put this decl out straight away.  */
   /* current_class_type can be NULL_TREE in case of error.  */
-  if (!asmspec && current_class_type)
-    {
-      DECL_INITIAL (decl) = error_mark_node;
-      DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
-    }
+  if (!asmspec_tree && current_class_type)
+    DECL_INITIAL (decl) = error_mark_node;
+
   if (! processing_template_decl)
     {
       if (!pending_statics)
@@ -1672,12 +1608,6 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
       if (CLASS_TYPE_P (TREE_TYPE (value)))
         CLASSTYPE_GOT_SEMICOLON (TREE_TYPE (value)) = 1;
       
-      /* Now that we've updated the context, we need to remangle the
-        name for this TYPE_DECL.  */
-      DECL_ASSEMBLER_NAME (value) = DECL_NAME (value);
-      if (!uses_template_parms (value)) 
-       DECL_ASSEMBLER_NAME (value) = mangle_type (TREE_TYPE (value));
-
       if (processing_template_decl)
        value = push_template_decl (value);
 
@@ -1775,8 +1705,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
        {
          /* This must override the asm specifier which was placed
             by grokclassfn.  Lay this out fresh.  */
-         DECL_RTL (value) = NULL_RTX;
-         DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec);
+         SET_DECL_RTL (value, NULL_RTX);
+         SET_DECL_ASSEMBLER_NAME (value, get_identifier (asmspec));
        }
       cp_finish_decl (value, init, asmspec_tree, flags);
 
@@ -1928,25 +1858,8 @@ grok_function_init (decl, init)
 
   if (TREE_CODE (type) == FUNCTION_TYPE)
     cp_error ("initializer specified for non-member function `%D'", decl);
-#if 0
-  /* We'll check for this in finish_struct_1.  */
-  else if (DECL_VINDEX (decl) == NULL_TREE)
-    cp_error ("initializer specified for non-virtual member function `%D'", decl);
-#endif
   else if (integer_zerop (init))
     {
-#if 0
-      /* Mark this function as being "defined".  */
-      DECL_INITIAL (decl) = error_mark_node;
-      /* pure virtual destructors must be defined.  */
-      /* pure virtual needs to be defined (as abort) only when put in 
-        vtbl. For wellformed call, it should be itself. pr4737 */
-      if (!DECL_DESTRUCTOR_P (decl)))
-       {
-         /* Give this node rtl from `abort'.  */
-         DECL_RTL (decl) = DECL_RTL (abort_fndecl);
-       }
-#endif
       DECL_PURE_VIRTUAL_P (decl) = 1;
       if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
        {
@@ -1971,7 +1884,7 @@ cplus_decl_attributes (decl, attributes, prefix_attributes)
   if (TREE_CODE (decl) == TEMPLATE_DECL)
     decl = DECL_TEMPLATE_RESULT (decl);
 
-  decl_attributes (decl, attributes, prefix_attributes);
+  decl_attributes (decl, chainon (attributes, prefix_attributes));
 
   if (TREE_CODE (decl) == TYPE_DECL)
     SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl), TREE_TYPE (decl));
@@ -2167,12 +2080,9 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p)
   return main_decl;
 }
 
-/* Finish off the processing of a UNION_TYPE structure.
-   If there are static members, then all members are
-   static, and must be laid out together.  If the
-   union is an anonymous union, we arrange for that
-   as well.  PUBLIC_P is nonzero if this union is
-   not declared static.  */
+/* Finish off the processing of a UNION_TYPE structure.  If the union is an
+   anonymous union, then all members must be laid out together.  PUBLIC_P
+   is nonzero if this union is not declared static.  */
 
 void
 finish_anon_union (anon_union_decl)
@@ -2184,6 +2094,9 @@ finish_anon_union (anon_union_decl)
   int static_p = TREE_STATIC (anon_union_decl);
   int external_p = DECL_EXTERNAL (anon_union_decl);
 
+  /* The VAR_DECL's context is the same as the TYPE's context. */
+  DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type));
+  
   if (TYPE_FIELDS (type) == NULL_TREE)
     return;
 
@@ -2206,7 +2119,7 @@ finish_anon_union (anon_union_decl)
   if (static_p)
     {
       make_decl_rtl (main_decl, 0);
-      DECL_RTL (anon_union_decl) = DECL_RTL (main_decl);
+      COPY_DECL_RTL (main_decl, anon_union_decl);
       expand_anon_union_decl (anon_union_decl, 
                              NULL_TREE,
                              DECL_ANON_UNION_ELEMS (anon_union_decl));
@@ -2343,7 +2256,7 @@ mark_vtable_entries (decl)
 
       if (TREE_CODE (fnaddr) != ADDR_EXPR)
        /* This entry is an offset: a virtual base class offset, a
-          virtual call offset, and RTTI offset, etc.  */
+          virtual call offset, an RTTI offset, etc.  */
        continue;
 
       fn = TREE_OPERAND (fnaddr, 0);
@@ -2353,7 +2266,7 @@ mark_vtable_entries (decl)
         we know all the thunks we'll need when we emit a virtual
         function, so we emit the thunks there instead.  */
       if (DECL_THUNK_P (fn)) 
-       use_thunk (fn, THUNK_GENERATE_WITH_VTABLE_P (fn));
+       use_thunk (fn, /*emit_p=*/0);
       mark_used (fn);
     }
 }
@@ -2425,7 +2338,7 @@ maybe_make_one_only (decl)
      after a weak one is an error.  Also, not making explicit
      instantiations one_only means that we can end up with two copies of
      some template instantiations. */
-  if (! supports_one_only ())
+  if (! flag_weak)
     return;
 
   /* We can't set DECL_COMDAT on functions, or finish_file will think
@@ -2456,8 +2369,13 @@ key_method (type)
   for (method = TYPE_METHODS (type); method != NULL_TREE;
        method = TREE_CHAIN (method))
     if (DECL_VINDEX (method) != NULL_TREE
-       && ! DECL_THIS_INLINE (method)
-       && ! DECL_PURE_VIRTUAL_P (method))
+       && ! DECL_DECLARED_INLINE_P (method)
+       && (! DECL_PURE_VIRTUAL_P (method)
+#if 0
+           /* This would be nice, but we didn't think of it in time.  */
+           || DECL_DESTRUCTOR_P (method)
+#endif
+           ))
       return method;
 
   return NULL_TREE;
@@ -2486,7 +2404,7 @@ import_export_vtable (decl, type, final)
   else if (CLASSTYPE_INTERFACE_KNOWN (type))
     {
       TREE_PUBLIC (decl) = 1;
-      DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type);
+      DECL_EXTERNAL (decl) = CLASSTYPE_INTERFACE_ONLY (type);
       DECL_INTERFACE_KNOWN (decl) = 1;
     }
   else
@@ -2538,13 +2456,18 @@ import_export_class (ctype)
   if (CLASSTYPE_INTERFACE_ONLY (ctype))
     return;
 
-#ifdef VALID_MACHINE_TYPE_ATTRIBUTE
-  /* FIXME this should really use some sort of target-independent macro.  */
-  if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype)))
+  if ((*targetm.valid_type_attribute) (ctype,
+                                      TYPE_ATTRIBUTES (ctype),
+                                      get_identifier ("dllimport"),
+                                      NULL_TREE)
+      && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype)))
     import_export = -1;
-  else if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype)))
+  else if ((*targetm.valid_type_attribute) (ctype,
+                                           TYPE_ATTRIBUTES (ctype),
+                                           get_identifier ("dllexport"),
+                                           NULL_TREE)
+          && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype)))
     import_export = 1;
-#endif
 
   /* If we got -fno-implicit-templates, we import template classes that
      weren't explicitly instantiated.  */
@@ -2571,7 +2494,6 @@ import_export_class (ctype)
   if (import_export)
     {
       SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
-      CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = (import_export > 0);
       CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0);
     }
 }
@@ -2656,7 +2578,7 @@ finish_vtable_vardecl (t, data)
       if (flag_weak)
        comdat_linkage (vars);
 
-      rest_of_decl_compilation (vars, NULL_PTR, 1, 1);
+      rest_of_decl_compilation (vars, NULL, 1, 1);
 
       if (flag_vtable_gc)
        output_vtable_inherit (vars);
@@ -2708,7 +2630,8 @@ import_export_decl (decl)
       if ((DECL_IMPLICIT_INSTANTIATION (decl)
           || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl))
          && (flag_implicit_templates
-             || (flag_implicit_inline_templates && DECL_THIS_INLINE (decl))))
+             || (flag_implicit_inline_templates 
+                 && DECL_DECLARED_INLINE_P (decl))))
        {
          if (!TREE_PUBLIC (decl))
            /* Templates are allowed to have internal linkage.  See 
@@ -2722,26 +2645,29 @@ import_export_decl (decl)
     }
   else if (DECL_FUNCTION_MEMBER_P (decl))
     {
-      tree ctype = DECL_CONTEXT (decl);
-      import_export_class (ctype);
-      if (CLASSTYPE_INTERFACE_KNOWN (ctype)
-         && ! DECL_THIS_INLINE (decl))
+      if (!DECL_DECLARED_INLINE_P (decl))
        {
-         DECL_NOT_REALLY_EXTERN (decl)
-           = ! (CLASSTYPE_INTERFACE_ONLY (ctype)
-                || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines
-                    && !DECL_VINDEX (decl)));
-
-         /* Always make artificials weak.  */
-         if (DECL_ARTIFICIAL (decl) && flag_weak)
-           comdat_linkage (decl);
-         else
-           maybe_make_one_only (decl);
+         tree ctype = DECL_CONTEXT (decl);
+         import_export_class (ctype);
+         if (CLASSTYPE_INTERFACE_KNOWN (ctype))
+           {
+             DECL_NOT_REALLY_EXTERN (decl)
+               = ! (CLASSTYPE_INTERFACE_ONLY (ctype)
+                    || (DECL_DECLARED_INLINE_P (decl) 
+                        && ! flag_implement_inlines
+                        && !DECL_VINDEX (decl)));
+
+             /* Always make artificials weak.  */
+             if (DECL_ARTIFICIAL (decl) && flag_weak)
+               comdat_linkage (decl);
+             else
+               maybe_make_one_only (decl);
+           }
        }
       else
        comdat_linkage (decl);
     }
-  else if (DECL_TINFO_FN_P (decl))
+  else if (tinfo_decl_p (decl, 0))
     {
       tree ctype = TREE_TYPE (DECL_NAME (decl));
 
@@ -2763,7 +2689,8 @@ import_export_decl (decl)
        {
          DECL_NOT_REALLY_EXTERN (decl)
            = ! (CLASSTYPE_INTERFACE_ONLY (ctype)
-                || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines
+                || (DECL_DECLARED_INLINE_P (decl) 
+                    && ! flag_implement_inlines
                     && !DECL_VINDEX (decl)));
 
          /* Always make artificials weak.  */
@@ -2999,7 +2926,7 @@ finish_objects (method_type, initp, body)
                  linker sorts in increasing order.  */
               MAX_INIT_PRIORITY - initp);
       named_section (NULL_TREE, buf, 0);
-      assemble_integer (gen_rtx_SYMBOL_REF (Pmode, fnname),
+      assemble_integer (XEXP (DECL_RTL (fn), 0),
                        POINTER_SIZE / BITS_PER_UNIT, 1);
     }
 #endif
@@ -3275,10 +3202,13 @@ start_static_initialization_or_destruction (decl, initp)
          my_friendly_assert (initp, 20000629);
          guard_cond = get_guard_cond (guard);
        }
-      /* Under the old ABI, e do initializations only if the GUARD is
-        zero, i.e., if we are the first to initialize the variable.
-        We do destructions only if the GUARD is one, i.e., if we are
-        the last to destroy the variable.  */
+      /* If we don't have __cxa_atexit, then we will be running
+        destructors from .fini sections, or their equivalents.  So,
+        we need to know how many times we've tried to initialize this
+        object.  We do initializations only if the GUARD is zero,
+        i.e., if we are the first to initialize the variable.  We do
+        destructions only if the GUARD is one, i.e., if we are the
+        last to destroy the variable.  */
       else if (initp)
        guard_cond 
          = cp_build_binary_op (EQ_EXPR,
@@ -3299,9 +3229,9 @@ start_static_initialization_or_destruction (decl, initp)
 
   finish_if_stmt_cond (cond, guard_if_stmt);
 
-  /* Under the new ABI, we have not already set the GUARD, so we must
-     do so now.  */
-  if (guard && initp)
+  /* If we're using __cxa_atexit, we have not already set the GUARD,
+     so we must do so now.  */
+  if (guard && initp && flag_use_cxa_atexit)
     finish_expr_stmt (set_guard (guard));
 
   return guard_if_stmt;
@@ -3671,10 +3601,6 @@ finish_file ()
            }
        }
 
-      /* Mark all functions that might deal with exception-handling as
-        referenced.  */
-      mark_all_runtime_matches ();
-
       /* We lie to the back-end, pretending that some functions are
         not defined when they really are.  This keeps these functions
         from being put out unnecessarily.  But, we must stop lying
@@ -3780,9 +3706,17 @@ finish_file ()
 
   /* The entire file is now complete.  If requested, dump everything
      to a file.   */
-  if (flag_dump_translation_unit)
-    dump_node_to_file (global_namespace, flag_dump_translation_unit);
+  {
+    int flags;
+    FILE *stream = dump_begin (TDI_all, &flags);
 
+    if (stream)
+      {
+       dump_node (global_namespace, flags & ~TDF_SLIM, stream);
+       dump_end (TDI_all, stream);
+      }
+  }
+  
   /* If there's some tool that wants to examine the entire translation
      unit, let it do so now.  */
   if (back_end_hook)
@@ -4216,8 +4150,6 @@ tree
 finish_decl_parsing (decl)
      tree decl;
 {
-  extern int current_class_depth;
-  
   switch (TREE_CODE (decl))
     {
     case IDENTIFIER_NODE:
@@ -4536,6 +4468,9 @@ set_decl_namespace (decl, scope, friendp)
       if (!old)
        /* No old declaration at all. */
        goto complain;
+      /* A template can be explicitly specialized in any namespace.  */
+      if (processing_explicit_instantiation)
+       return;
       if (!is_overloaded_fn (decl))
        /* Don't compare non-function decls with decls_match here,
           since it can't check for the correct constness at this
@@ -5029,16 +4964,6 @@ validate_nonmember_using_decl (decl, scope, name)
   if (TREE_CODE (decl) == SCOPE_REF
       && TREE_OPERAND (decl, 0) == fake_std_node)
     {
-      if (namespace_bindings_p ()
-         && current_namespace == global_namespace)
-       /* There's no need for a using declaration at all, here,
-          since `std' is the same as `::'.  We can't just pass this
-          on because we'll complain later about declaring something
-          in the same scope as a using declaration with the same
-          name.  We return NULL_TREE which indicates to the caller
-          that there's no need to do any further processing.  */
-       return NULL_TREE;
-
       *scope = global_namespace;
       *name = TREE_OPERAND (decl, 1);
     }
@@ -5051,7 +4976,8 @@ validate_nonmember_using_decl (decl, scope, name)
 
         A using-declaration for a class member shall be a
         member-declaration.  */
-      if (TREE_CODE (*scope) != NAMESPACE_DECL)
+      if (!processing_template_decl
+          && TREE_CODE (*scope) != NAMESPACE_DECL)
        {
          if (TYPE_P (*scope))
            cp_error ("`%T' is not a namespace", *scope);
@@ -5123,22 +5049,21 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
            {
              tree old_fn = OVL_CURRENT (tmp1);
 
-             if (!OVL_USED (tmp1)
-                 && compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
-                               TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+              if (new_fn == old_fn)
+                /* The function already exists in the current namespace.  */
+                break;
+             else if (OVL_USED (tmp1))
+               continue; /* this is a using decl */
+             else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
+                                 TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
                {
-                 if (!(DECL_EXTERN_C_P (new_fn)
-                       && DECL_EXTERN_C_P (old_fn)))
-                   /* There was already a non-using declaration in
-                      this scope with the same parameter types.  */
-                   cp_error ("`%D' is already declared in this scope",
-                             name);
+                 /* There was already a non-using declaration in
+                    this scope with the same parameter types. If both
+                    are the same extern "C" functions, that's ok.  */
+                  if (!decls_match (new_fn, old_fn))
+                   cp_error ("`%D' is already declared in this scope", name);
                  break;
                }
-             else if (duplicate_decls (new_fn, old_fn))
-               /* We're re-using something we already used 
-                  before.  We don't need to add it again.  */ 
-               break;
            }
 
          /* If we broke out of the loop, there's no reason to add
@@ -5210,6 +5135,10 @@ do_local_using_decl (decl)
   if (decl == NULL_TREE)
     return;
 
+  if (building_stmt_tree ()
+      && at_function_scope_p ())
+    add_decl_stmt (decl);
+
   oldval = lookup_name_current_level (name);
   oldtype = lookup_type_current_level (name);
 
@@ -5277,18 +5206,23 @@ do_using_directive (namespace)
 {
   if (namespace == fake_std_node)
     return;
+  if (building_stmt_tree ())
+    add_stmt (build_stmt (USING_STMT, namespace));
+  
   /* using namespace A::B::C; */
   if (TREE_CODE (namespace) == SCOPE_REF)
       namespace = TREE_OPERAND (namespace, 1);
   if (TREE_CODE (namespace) == IDENTIFIER_NODE)
     {
       /* Lookup in lexer did not find a namespace. */
-      cp_error ("namespace `%T' undeclared", namespace);
+      if (!processing_template_decl)
+       cp_error ("namespace `%T' undeclared", namespace);
       return;
     }
   if (TREE_CODE (namespace) != NAMESPACE_DECL)
     {
-      cp_error ("`%T' is not a namespace", namespace);
+      if (!processing_template_decl)
+       cp_error ("`%T' is not a namespace", namespace);
       return;
     }
   namespace = ORIGINAL_NAMESPACE (namespace);
@@ -5427,12 +5361,10 @@ handle_class_head (aggr, scope, id)
 void
 init_decl2 ()
 {
-  ggc_add_tree_root (&decl_namespace_list, 1);
   ggc_add_tree_varray_root (&deferred_fns, 1);
   ggc_add_tree_varray_root (&pending_statics, 1);
   ggc_add_tree_varray_root (&ssdf_decls, 1);
   ggc_add_tree_root (&ssdf_decl, 1);
   ggc_add_tree_root (&priority_decl, 1);
   ggc_add_tree_root (&initialize_p_decl, 1);
-  ggc_add_tree_root (&pending_vtables, 1);
 }