OSDN Git Service

* c-common.c (decl_attributes): Only take a single attributes
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl2.c
index 99e5591..e6d4274 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
 /* Process declarations and variables for C compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000 Free Software Foundation, Inc.
+   1999, 2000, 2001 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -39,13 +39,13 @@ Boston, MA 02111-1307, USA.  */
 #include "lex.h"
 #include "output.h"
 #include "except.h"
 #include "lex.h"
 #include "output.h"
 #include "except.h"
-#include "defaults.h"
 #include "toplev.h"
 #include "dwarf2out.h"
 #include "dwarfout.h"
 #include "ggc.h"
 #include "timevar.h"
 #include "cpplib.h"
 #include "toplev.h"
 #include "dwarf2out.h"
 #include "dwarfout.h"
 #include "ggc.h"
 #include "timevar.h"
 #include "cpplib.h"
+#include "target.h"
 extern cpp_reader *parse_in;
 
 /* This structure contains information about the initializations
 extern cpp_reader *parse_in;
 
 /* This structure contains information about the initializations
@@ -93,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));
 
 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.  */
 /* 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.  */
@@ -131,23 +126,9 @@ tree static_dtors;
 /* The :: namespace. */
 
 tree global_namespace;
 /* 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.  */
 
 \f
 /* C (and C++) language-specific option variables.  */
 
-/* Nonzero means allow type mismatches in conditional expressions;
-   just make their values `void'.   */
-
-int flag_cond_mismatch;
-
-/* Nonzero means give `double' the same size as `float'.  */
-
-int flag_short_double;
-
 /* Nonzero means don't recognize the keyword `asm'.  */
 
 int flag_no_asm;
 /* Nonzero means don't recognize the keyword `asm'.  */
 
 int flag_no_asm;
@@ -213,10 +194,7 @@ int warn_ctor_dtor_privacy = 1;
 /* True if we want to implement vtables using "thunks".
    The default is off.  */
 
 /* True if we want to implement vtables using "thunks".
    The default is off.  */
 
-#ifndef DEFAULT_VTABLE_THUNKS
-#define DEFAULT_VTABLE_THUNKS 0
-#endif
-int flag_vtable_thunks = DEFAULT_VTABLE_THUNKS;
+int flag_vtable_thunks = 1;
 
 /* Nonzero means generate separate instantiation control files and juggle
    them at link time.  */
 
 /* Nonzero means generate separate instantiation control files and juggle
    them at link time.  */
@@ -288,23 +266,25 @@ int warn_parentheses;
 /* Non-zero means warn in function declared in derived class has the
    same name as a virtual in the base class, but fails to match the
    type signature of any virtual function in the base class.  */
 /* Non-zero means warn in function declared in derived class has the
    same name as a virtual in the base class, but fails to match the
    type signature of any virtual function in the base class.  */
+
 int warn_overloaded_virtual;
 
 /* Non-zero means warn when declaring a class that has a non virtual
    destructor, when it really ought to have a virtual one.  */
 int warn_overloaded_virtual;
 
 /* Non-zero means warn when declaring a class that has a non virtual
    destructor, when it really ought to have a virtual one.  */
-int warn_nonvdtor;
 
 
-/* Non-zero means warn when a function is declared extern and later inline.  */
-int warn_extern_inline;
+int warn_nonvdtor;
 
 /* Non-zero means warn when the compiler will reorder code.  */
 
 /* Non-zero means warn when the compiler will reorder code.  */
+
 int warn_reorder;
 
 /* Non-zero means warn when synthesis behavior differs from Cfront's.  */
 int warn_reorder;
 
 /* Non-zero means warn when synthesis behavior differs from Cfront's.  */
+
 int warn_synth;
 
 /* Non-zero means warn when we convert a pointer to member function
    into a pointer to (void or function).  */
 int warn_synth;
 
 /* Non-zero means warn when we convert a pointer to member function
    into a pointer to (void or function).  */
+
 int warn_pmf2ptr = 1;
 
 /* Nonzero means warn about violation of some Effective C++ style rules.  */
 int warn_pmf2ptr = 1;
 
 /* Nonzero means warn about violation of some Effective C++ style rules.  */
@@ -344,20 +324,11 @@ int warn_deprecated = 1;
 #endif
 int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
 
 #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;
 
 /* C++ specific flags.  */   
 /* Nonzero means allow Microsoft extensions without a pedwarn.  */
 
 int flag_ms_extensions;
 
 /* C++ specific flags.  */   
-/* Zero means that `this' is a *const.  This gives nice behavior in the
-   2.0 world.  1 gives 1.2-compatible behavior.  2 gives Spring behavior.
-   -2 means we're constructing an object and it has fixed type.  */
-
-int flag_this_is_variable;
 
 /* Nonzero means we should attempt to elide constructors when possible.  */
 
 
 /* Nonzero means we should attempt to elide constructors when possible.  */
 
@@ -370,11 +341,8 @@ int flag_default_inline = 1;
 
 /* Controls whether compiler generates 'type descriptor' that give
    run-time type information.  */
 
 /* Controls whether compiler generates 'type descriptor' that give
    run-time type information.  */
-int flag_rtti = 1;
 
 
-/* Nonzero if we wish to output cross-referencing information
-   for the GNU class browser.  */
-extern int flag_gnu_xref;
+int flag_rtti = 1;
 
 /* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
    objects.  */
 
 /* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
    objects.  */
@@ -416,10 +384,6 @@ int flag_new_for_scope = 1;
 
 int flag_weak = 1;
 
 
 int flag_weak = 1;
 
-/* Nonzero to enable experimental ABI changes.  */
-
-int flag_new_abi;
-
 /* Nonzero to use __cxa_atexit, rather than atexit, to register
    destructors for local statics and global objects.  */
 
 /* Nonzero to use __cxa_atexit, rather than atexit, to register
    destructors for local statics and global objects.  */
 
@@ -427,31 +391,20 @@ int flag_use_cxa_atexit;
 
 /* Nonzero to not ignore namespace std. */
 
 
 /* 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;
 
 
 int flag_inline_trees = 0;
 
-/* Maximum template instantiation depth. Must be at least 17 for ISO
-   compliance. */
-
-int max_tinst_depth = 17;
-
-/* The name-mangling scheme to use.  Must be 1 or greater to support
-   template functions with identical types, but different template
-   arguments.  */
-int name_mangling_version = 2;
+/* Maximum template instantiation depth.  This limit is rather
+   arbitrary, but it exists to limit the time it takes to notice
+   infinite template instantiations.  */
 
 
-/* Nonzero if wchar_t should be `unsigned short' instead of whatever it
-   would normally be, for use with WINE.  */
-int flag_short_wchar;
-
-/* Nonzero if squashed mangling is to be performed. 
-   This uses the B and K codes to reference previously seen class types 
-   and class qualifiers.       */
-int flag_do_squangling;
+int max_tinst_depth = 50;
 
 /* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc.  */
 
 
 /* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc.  */
 
@@ -490,7 +443,6 @@ lang_f_options[] =
   {"short-enums", &flag_short_enums, 1},
   {"short-double", &flag_short_double, 1},
   {"short-wchar", &flag_short_wchar, 1},
   {"short-enums", &flag_short_enums, 1},
   {"short-double", &flag_short_double, 1},
   {"short-wchar", &flag_short_wchar, 1},
-  {"cond-mismatch", &flag_cond_mismatch, 1},
   {"asm", &flag_no_asm, 0},
   {"builtin", &flag_no_builtin, 0},
 
   {"asm", &flag_no_asm, 0},
   {"builtin", &flag_no_builtin, 0},
 
@@ -508,11 +460,9 @@ lang_f_options[] =
   {"gnu-keywords", &flag_no_gnu_keywords, 0},
   {"handle-exceptions", &flag_exceptions, 1},
   {"honor-std", &flag_honor_std, 1},
   {"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},
   {"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},
   {"ms-extensions", &flag_ms_extensions, 1},
   {"nonansi-builtins", &flag_no_nonansi_builtin, 0},
   {"operator-names", &flag_operator_names, 1},
@@ -520,13 +470,10 @@ lang_f_options[] =
   {"permissive", &flag_permissive, 1},
   {"repo", &flag_use_repository, 1},
   {"rtti", &flag_rtti, 1},
   {"permissive", &flag_permissive, 1},
   {"repo", &flag_use_repository, 1},
   {"rtti", &flag_rtti, 1},
-  {"squangle", &flag_do_squangling, 1},
   {"stats", &flag_detailed_statistics, 1},
   {"stats", &flag_detailed_statistics, 1},
-  {"use-cxa-atexit", &flag_use_cxa_atexit, 1},
   {"vtable-gc", &flag_vtable_gc, 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'
 };
 
 /* The list of `-f' options that we no longer support.  The `-f'
@@ -534,11 +481,18 @@ lang_f_options[] =
    listed here.  This table must be kept in alphabetical order.  */
 static const char * const unsupported_options[] = {
   "all-virtual",
    listed here.  This table must be kept in alphabetical order.  */
 static const char * const unsupported_options[] = {
   "all-virtual",
+  "cond-mismatch",
   "enum-int-equiv",
   "guiding-decls",
   "enum-int-equiv",
   "guiding-decls",
+  "huge-objects",
+  "labels-ok",
+  "new-abi",
   "nonnull-objects",
   "nonnull-objects",
-  "this-is-variable",
+  "squangle",
   "strict-prototype",
   "strict-prototype",
+  "this-is-variable",
+  "vtable-thunks",
+  "xref"
 };
 
 /* Compare two option strings, pointed two by P1 and P2, for use with
 };
 
 /* Compare two option strings, pointed two by P1 and P2, for use with
@@ -558,7 +512,7 @@ compare_options (p1, p2)
    recognise the option.  */
 
 int   
    recognise the option.  */
 
 int   
-lang_decode_option (argc, argv)
+cxx_decode_option (argc, argv)
      int argc;
      char **argv;
 {
      int argc;
      char **argv;
 {
@@ -623,33 +577,18 @@ lang_decode_option (argc, argv)
           flag_external_templates = 1;
           cp_deprecated ("-fexternal-templates");
         }
           flag_external_templates = 1;
           cp_deprecated ("-fexternal-templates");
         }
-      else if (!strcmp (p, "new-abi"))
-       {
-         flag_new_abi = 1;
-         flag_do_squangling = 1;
-         flag_vtable_thunks = 1;
-       }
-      else if (!strcmp (p, "no-new-abi"))
-       {
-         flag_new_abi = 0;
-         flag_do_squangling = 0;
-       }
       else if ((option_value
                 = skip_leading_substring (p, "template-depth-")))
        max_tinst_depth
          = read_integral_parameter (option_value, p - 2, max_tinst_depth);
       else if ((option_value
                 = skip_leading_substring (p, "name-mangling-version-")))
       else if ((option_value
                 = skip_leading_substring (p, "template-depth-")))
        max_tinst_depth
          = read_integral_parameter (option_value, p - 2, max_tinst_depth);
       else if ((option_value
                 = skip_leading_substring (p, "name-mangling-version-")))
-       name_mangling_version 
-         = read_integral_parameter (option_value, p - 2, name_mangling_version);
-      else if ((option_value
-                = skip_leading_substring (p, "dump-translation-unit-")))
        {
        {
-         if (p[22] == '\0')
-           error ("no file specified with -fdump-translation-unit");
-         else
-           flag_dump_translation_unit = option_value;
+         warning ("-fname-mangling-version is no longer supported");
+         return 1;
        }
        }
+      else if (dump_switch_p (p))
+       ;
       else 
        {
          int found = 0;
       else 
        {
          int found = 0;
@@ -720,12 +659,16 @@ lang_decode_option (argc, argv)
        warn_float_equal = setting;
       else if (!strcmp (p, "format"))
        set_Wformat (setting);
        warn_float_equal = setting;
       else if (!strcmp (p, "format"))
        set_Wformat (setting);
+      else if (!strcmp (p, "format=2"))
+       set_Wformat (2);
       else if (!strcmp (p, "format-y2k"))
        warn_format_y2k = setting;
       else if (!strcmp (p, "format-extra-args"))
        warn_format_extra_args = setting;
       else if (!strcmp (p, "format-nonliteral"))
        warn_format_nonliteral = setting;
       else if (!strcmp (p, "format-y2k"))
        warn_format_y2k = setting;
       else if (!strcmp (p, "format-extra-args"))
        warn_format_extra_args = setting;
       else if (!strcmp (p, "format-nonliteral"))
        warn_format_nonliteral = setting;
+      else if (!strcmp (p, "format-security"))
+       warn_format_security = setting;
       else if (!strcmp (p, "missing-format-attribute"))
        warn_missing_format_attribute = setting;
       else if (!strcmp (p, "conversion"))
       else if (!strcmp (p, "missing-format-attribute"))
        warn_missing_format_attribute = setting;
       else if (!strcmp (p, "conversion"))
@@ -734,8 +677,6 @@ lang_decode_option (argc, argv)
        warn_parentheses = setting;
       else if (!strcmp (p, "non-virtual-dtor"))
        warn_nonvdtor = setting;
        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"))
       else if (!strcmp (p, "reorder"))
        warn_reorder = setting;
       else if (!strcmp (p, "synth"))
@@ -926,6 +867,9 @@ build_artificial_parm (name, type)
 
   parm = build_decl (PARM_DECL, name, type);
   DECL_ARTIFICIAL (parm) = 1;
 
   parm = build_decl (PARM_DECL, name, type);
   DECL_ARTIFICIAL (parm) = 1;
+  /* All our artificial parms are implicitly `const'; they cannot be
+     assigned to.  */
+  TREE_READONLY (parm) = 1;
   DECL_ARG_TYPE (parm) = type;
   return parm;
 }
   DECL_ARG_TYPE (parm) = type;
   return parm;
 }
@@ -938,7 +882,10 @@ build_artificial_parm (name, type)
 
    This function adds the "in-charge" flag to member function FN if
    appropriate.  It is called from grokclassfn and tsubst.
 
    This function adds the "in-charge" flag to member function FN if
    appropriate.  It is called from grokclassfn and tsubst.
-   FN must be either a constructor or destructor.  */
+   FN must be either a constructor or destructor.
+
+   The in-charge flag follows the 'this' parameter, and is followed by the
+   VTT parm (if any), then the user-written parms.  */
 
 void
 maybe_retrofit_in_chrg (fn)
 
 void
 maybe_retrofit_in_chrg (fn)
@@ -961,17 +908,38 @@ maybe_retrofit_in_chrg (fn)
       && !TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
     return;
 
       && !TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
     return;
 
-  /* First add it to DECL_ARGUMENTS...  */
-  parm = build_artificial_parm (in_charge_identifier, integer_type_node);
-  TREE_READONLY (parm) = 1;
-  parms = DECL_ARGUMENTS (fn);
-  TREE_CHAIN (parm) = TREE_CHAIN (parms);
-  TREE_CHAIN (parms) = parm;
-
-  /* ...and then to TYPE_ARG_TYPES.  */
   arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
   basetype = TREE_TYPE (TREE_VALUE (arg_types));
   arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
   basetype = TREE_TYPE (TREE_VALUE (arg_types));
-  arg_types = hash_tree_chain (integer_type_node, TREE_CHAIN (arg_types));
+  arg_types = TREE_CHAIN (arg_types);
+
+  parms = TREE_CHAIN (DECL_ARGUMENTS (fn));
+
+  /* If this is a subobject constructor or destructor, our caller will
+     pass us a pointer to our VTT.  */
+  if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
+    {
+      parm = build_artificial_parm (vtt_parm_identifier, vtt_parm_type);
+
+      /* First add it to DECL_ARGUMENTS between 'this' and the real args...  */
+      TREE_CHAIN (parm) = parms;
+      parms = parm;
+
+      /* ...and then to TYPE_ARG_TYPES.  */
+      arg_types = hash_tree_chain (vtt_parm_type, arg_types);
+
+      DECL_HAS_VTT_PARM_P (fn) = 1;
+    }
+
+  /* Then add the in-charge parm (before the VTT parm).  */
+  parm = build_artificial_parm (in_charge_identifier, integer_type_node);
+  TREE_CHAIN (parm) = parms;
+  parms = parm;
+  arg_types = hash_tree_chain (integer_type_node, arg_types);
+
+  /* Insert our new parameter(s) into the list.  */
+  TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms;
+
+  /* And rebuild the function type.  */
   fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)),
                                    arg_types);
   if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
   fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)),
                                    arg_types);
   if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
@@ -981,18 +949,6 @@ maybe_retrofit_in_chrg (fn)
 
   /* Now we've got the in-charge parameter.  */
   DECL_HAS_IN_CHARGE_PARM_P (fn) = 1;
 
   /* Now we've got the in-charge parameter.  */
   DECL_HAS_IN_CHARGE_PARM_P (fn) = 1;
-
-  /* If this is a subobject constructor or destructor, our caller will
-     pass us a pointer to our VTT.  */
-  if (flag_new_abi && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
-    {
-      DECL_VTT_PARM (fn) = build_artificial_parm (vtt_parm_identifier, 
-                                                 vtt_parm_type);
-      DECL_CONTEXT (DECL_VTT_PARM (fn)) = fn;
-      DECL_USE_VTT_PARM (fn) = build_artificial_parm (NULL_TREE,
-                                                     boolean_type_node);
-      DECL_CONTEXT (DECL_USE_VTT_PARM (fn)) = fn;
-    }
 }
 
 /* Classes overload their constituent function names automatically.
 }
 
 /* Classes overload their constituent function names automatically.
@@ -1026,7 +982,7 @@ grokclassfn (ctype, function, flags, quals)
 
   /* Even within an `extern "C"' block, members get C++ linkage.  See
      [dcl.link] for details.  */
 
   /* 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)
     {
 
   if (fn_name == NULL_TREE)
     {
@@ -1064,22 +1020,17 @@ grokclassfn (ctype, function, flags, quals)
   DECL_ARGUMENTS (function) = last_function_parms;
   DECL_CONTEXT (function) = ctype;
 
   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;
   if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))
     maybe_retrofit_in_chrg (function);
 
   if (flags == DTOR_FLAG)
     {
       DECL_DESTRUCTOR_P (function) = 1;
-
-      if (flag_new_abi) 
-       set_mangled_name_for_decl (function);
-      else
-       DECL_ASSEMBLER_NAME (function) = build_destructor_name (ctype);
-
       TYPE_HAS_DESTRUCTOR (ctype) = 1;
     }
       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).  */
 }
 
 /* Work on the expr used by alignof (this is only called by the parser).  */
@@ -1335,7 +1286,7 @@ acceptable_java_type (type)
 {
   if (TREE_CODE (type) == VOID_TYPE || TYPE_FOR_JAVA (type))
     return 1;
 {
   if (TREE_CODE (type) == VOID_TYPE || TYPE_FOR_JAVA (type))
     return 1;
-  if (TREE_CODE (type) == POINTER_TYPE)
+  if (TREE_CODE (type) == POINTER_TYPE || TREE_CODE (type) == REFERENCE_TYPE)
     {
       type = TREE_TYPE (type);
       if (TREE_CODE (type) == RECORD_TYPE)
     {
       type = TREE_TYPE (type);
       if (TREE_CODE (type) == RECORD_TYPE)
@@ -1444,22 +1395,6 @@ check_classfn (ctype, function)
                   fndecls = OVL_NEXT (fndecls))
                {
                  fndecl = OVL_CURRENT (fndecls);
                   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 
 
                  /* We cannot simply call decls_match because this
                     doesn't work for static member functions that are 
@@ -1533,28 +1468,17 @@ finish_static_data_member_decl (decl, init, asmspec_tree, flags)
      tree asmspec_tree;
      int 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
   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.  */
      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;
-      if (flag_new_abi)
-       DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
-      else
-       DECL_ASSEMBLER_NAME (decl) 
-         = build_static_name (current_class_type, DECL_NAME (decl));
-    }
+  if (!asmspec_tree && current_class_type)
+    DECL_INITIAL (decl) = error_mark_node;
+
   if (! processing_template_decl)
     {
       if (!pending_statics)
   if (! processing_template_decl)
     {
       if (!pending_statics)
@@ -1684,18 +1608,6 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
       if (CLASS_TYPE_P (TREE_TYPE (value)))
         CLASSTYPE_GOT_SEMICOLON (TREE_TYPE (value)) = 1;
       
       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)) 
-       {
-         if (flag_new_abi)
-           DECL_ASSEMBLER_NAME (value) = mangle_type (TREE_TYPE (value));
-         else
-           DECL_ASSEMBLER_NAME (value) =
-             get_identifier (build_overload_name (TREE_TYPE (value), 1, 1));
-       }
-
       if (processing_template_decl)
        value = push_template_decl (value);
 
       if (processing_template_decl)
        value = push_template_decl (value);
 
@@ -1779,15 +1691,10 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
   if (TREE_CODE (value) == FIELD_DECL)
     {
       if (asmspec)
   if (TREE_CODE (value) == FIELD_DECL)
     {
       if (asmspec)
-       {
-         /* 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);
-       }
+       cp_error ("`asm' specifiers are not permitted on non-static data members");
       if (DECL_INITIAL (value) == error_mark_node)
        init = error_mark_node;
       if (DECL_INITIAL (value) == error_mark_node)
        init = error_mark_node;
-      cp_finish_decl (value, init, asmspec_tree, flags);
+      cp_finish_decl (value, init, NULL_TREE, flags);
       DECL_INITIAL (value) = init;
       DECL_IN_AGGR_P (value) = 1;
       return value;
       DECL_INITIAL (value) = init;
       DECL_IN_AGGR_P (value) = 1;
       return value;
@@ -1798,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.  */
        {
          /* 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);
 
        }
       cp_finish_decl (value, init, asmspec_tree, flags);
 
@@ -1880,10 +1787,7 @@ grokoptypename (declspecs, declarator)
      tree declspecs, declarator;
 {
   tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL_TREE);
      tree declspecs, declarator;
 {
   tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL_TREE);
-  if (flag_new_abi)
-    return mangle_conv_op_name_for_type (t);
-  else
-    return build_typename_overload (t);
+  return mangle_conv_op_name_for_type (t);
 }
 
 /* When a function is declared with an initializer,
 }
 
 /* When a function is declared with an initializer,
@@ -1954,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 (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))
     {
   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)
        {
       DECL_PURE_VIRTUAL_P (decl) = 1;
       if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
        {
@@ -1997,7 +1884,7 @@ cplus_decl_attributes (decl, attributes, prefix_attributes)
   if (TREE_CODE (decl) == TEMPLATE_DECL)
     decl = DECL_TEMPLATE_RESULT (decl);
 
   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));
 
   if (TREE_CODE (decl) == TYPE_DECL)
     SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl), TREE_TYPE (decl));
@@ -2193,12 +2080,9 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p)
   return main_decl;
 }
 
   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)
 
 void
 finish_anon_union (anon_union_decl)
@@ -2210,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);
 
   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;
 
   if (TYPE_FIELDS (type) == NULL_TREE)
     return;
 
@@ -2231,8 +2118,8 @@ finish_anon_union (anon_union_decl)
 
   if (static_p)
     {
 
   if (static_p)
     {
-      make_decl_rtl (main_decl, 0, toplevel_bindings_p ());
-      DECL_RTL (anon_union_decl) = DECL_RTL (main_decl);
+      make_decl_rtl (main_decl, 0);
+      COPY_DECL_RTL (main_decl, anon_union_decl);
       expand_anon_union_decl (anon_union_decl, 
                              NULL_TREE,
                              DECL_ANON_UNION_ELEMS (anon_union_decl));
       expand_anon_union_decl (anon_union_decl, 
                              NULL_TREE,
                              DECL_ANON_UNION_ELEMS (anon_union_decl));
@@ -2369,7 +2256,7 @@ mark_vtable_entries (decl)
 
       if (TREE_CODE (fnaddr) != ADDR_EXPR)
        /* This entry is an offset: a virtual base class offset, a
 
       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);
        continue;
 
       fn = TREE_OPERAND (fnaddr, 0);
@@ -2379,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)) 
         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);
     }
 }
       mark_used (fn);
     }
 }
@@ -2393,14 +2280,24 @@ comdat_linkage (decl)
 {
   if (flag_weak)
     make_decl_one_only (decl);
 {
   if (flag_weak)
     make_decl_one_only (decl);
-  else if (TREE_CODE (decl) == FUNCTION_DECL || DECL_VIRTUAL_P (decl))
-    /* We can just emit functions and vtables statically; having
-       multiple copies is (for the most part) only a waste of space.
-       There is at least one correctness issue, however: the address
-       of a template instantiation with external linkage should be the
+  else if (TREE_CODE (decl) == FUNCTION_DECL 
+          || (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)))
+    /* We can just emit function and compiler-generated variables
+       statically; having multiple copies is (for the most part) only
+       a waste of space.  
+
+       There are two correctness issues, however: the address of a
+       template instantiation with external linkage should be the
        same, independent of what translation unit asks for the
        address, and this will not hold when we emit multiple copies of
        same, independent of what translation unit asks for the
        address, and this will not hold when we emit multiple copies of
-       the function.  However, there's little else we can do.  */
+       the function.  However, there's little else we can do.  
+
+       Also, by default, the typeinfo implementation for the new ABI
+       assumes that there will be only one copy of the string used as
+       the name for each type.  Therefore, if weak symbols are
+       unavailable, the run-time library should perform a more
+       conservative check; it should perform a string comparison,
+       rather than an address comparison.  */
     TREE_PUBLIC (decl) = 0;
   else
     {
     TREE_PUBLIC (decl) = 0;
   else
     {
@@ -2441,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. */
      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
     return;
 
   /* We can't set DECL_COMDAT on functions, or finish_file will think
@@ -2472,8 +2369,13 @@ key_method (type)
   for (method = TYPE_METHODS (type); method != NULL_TREE;
        method = TREE_CHAIN (method))
     if (DECL_VINDEX (method) != NULL_TREE
   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;
       return method;
 
   return NULL_TREE;
@@ -2502,7 +2404,7 @@ import_export_vtable (decl, type, final)
   else if (CLASSTYPE_INTERFACE_KNOWN (type))
     {
       TREE_PUBLIC (decl) = 1;
   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
       DECL_INTERFACE_KNOWN (decl) = 1;
     }
   else
@@ -2554,13 +2456,18 @@ import_export_class (ctype)
   if (CLASSTYPE_INTERFACE_ONLY (ctype))
     return;
 
   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;
     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;
     import_export = 1;
-#endif
 
   /* If we got -fno-implicit-templates, we import template classes that
      weren't explicitly instantiated.  */
 
   /* If we got -fno-implicit-templates, we import template classes that
      weren't explicitly instantiated.  */
@@ -2587,7 +2494,6 @@ import_export_class (ctype)
   if (import_export)
     {
       SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
   if (import_export)
     {
       SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
-      CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = (import_export > 0);
       CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0);
     }
 }
       CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0);
     }
 }
@@ -2672,7 +2578,7 @@ finish_vtable_vardecl (t, data)
       if (flag_weak)
        comdat_linkage (vars);
 
       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);
 
       if (flag_vtable_gc)
        output_vtable_inherit (vars);
@@ -2724,7 +2630,8 @@ import_export_decl (decl)
       if ((DECL_IMPLICIT_INSTANTIATION (decl)
           || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl))
          && (flag_implicit_templates
       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 
        {
          if (!TREE_PUBLIC (decl))
            /* Templates are allowed to have internal linkage.  See 
@@ -2738,28 +2645,29 @@ import_export_decl (decl)
     }
   else if (DECL_FUNCTION_MEMBER_P (decl))
     {
     }
   else if (DECL_FUNCTION_MEMBER_P (decl))
     {
-      tree ctype = DECL_CONTEXT (decl);
-      import_export_class (ctype);
-      if (CLASSTYPE_INTERFACE_KNOWN (ctype)
-         && (flag_new_abi
-             ? (! DECL_THIS_INLINE (decl))
-             : (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (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
        comdat_linkage (decl);
     }
-  else if (DECL_TINFO_FN_P (decl))
+  else if (tinfo_decl_p (decl, 0))
     {
       tree ctype = TREE_TYPE (DECL_NAME (decl));
 
     {
       tree ctype = TREE_TYPE (DECL_NAME (decl));
 
@@ -2781,7 +2689,8 @@ import_export_decl (decl)
        {
          DECL_NOT_REALLY_EXTERN (decl)
            = ! (CLASSTYPE_INTERFACE_ONLY (ctype)
        {
          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.  */
                     && !DECL_VINDEX (decl)));
 
          /* Always make artificials weak.  */
@@ -2830,23 +2739,7 @@ get_guard (decl)
   tree sname;
   tree guard;
 
   tree sname;
   tree guard;
 
-  /* For a local variable, under the old ABI, we do not try to get a
-     unique mangled name for the DECL.  */
-  if (!flag_new_abi && DECL_FUNCTION_SCOPE_P (decl))
-    {
-      guard = get_temp_name (integer_type_node);
-      cp_finish_decl (guard, NULL_TREE, NULL_TREE, 0);
-      return guard;
-    }
-
-  if (!flag_new_abi)
-    /* For struct X foo __attribute__((weak)), there is a counter
-       __snfoo. Since base is already an assembler name, sname should
-       be globally unique */
-    sname = get_id_2 ("__sn", DECL_ASSEMBLER_NAME (decl));
-  else
-    sname = mangle_guard_variable (decl);
-
+  sname = mangle_guard_variable (decl);
   guard = IDENTIFIER_GLOBAL_VALUE (sname);
   if (! guard)
     {
   guard = IDENTIFIER_GLOBAL_VALUE (sname);
   if (! guard)
     {
@@ -2854,17 +2747,19 @@ get_guard (decl)
 
       /* Under the new ABI, we use a type that is big enough to
         contain a mutex as well as an integer counter.  */
 
       /* Under the new ABI, we use a type that is big enough to
         contain a mutex as well as an integer counter.  */
-      if (flag_new_abi)
-       guard_type = long_long_integer_type_node;
-      else
-       guard_type = integer_type_node;
-
+      guard_type = long_long_integer_type_node;
       guard = build_decl (VAR_DECL, sname, guard_type);
       guard = build_decl (VAR_DECL, sname, guard_type);
-      TREE_PUBLIC (guard) = 1;
+      
+      /* The guard should have the same linkage as what it guards. */
+      TREE_PUBLIC (guard) = TREE_PUBLIC (decl);
+      TREE_STATIC (guard) = TREE_STATIC (decl);
+      DECL_COMMON (guard) = DECL_COMMON (decl);
+      DECL_ONE_ONLY (guard) = DECL_ONE_ONLY (decl);
+      if (TREE_PUBLIC (decl))
+        DECL_WEAK (guard) = DECL_WEAK (decl);
+      
       DECL_ARTIFICIAL (guard) = 1;
       DECL_ARTIFICIAL (guard) = 1;
-      TREE_STATIC (guard) = 1;
       TREE_USED (guard) = 1;
       TREE_USED (guard) = 1;
-      DECL_COMMON (guard) = 1;
       pushdecl_top_level (guard);
       cp_finish_decl (guard, NULL_TREE, NULL_TREE, 0);
     }
       pushdecl_top_level (guard);
       cp_finish_decl (guard, NULL_TREE, NULL_TREE, 0);
     }
@@ -2878,9 +2773,6 @@ static tree
 get_guard_bits (guard)
      tree guard;
 {
 get_guard_bits (guard)
      tree guard;
 {
-  if (!flag_new_abi)
-    return guard;
-
   /* Under the new ABI, we only set the first byte of the guard,
      in order to leave room for a mutex in the high-order bits.  */
   guard = build1 (ADDR_EXPR, 
   /* Under the new ABI, we only set the first byte of the guard,
      in order to leave room for a mutex in the high-order bits.  */
   guard = build1 (ADDR_EXPR, 
@@ -3034,7 +2926,7 @@ finish_objects (method_type, initp, body)
                  linker sorts in increasing order.  */
               MAX_INIT_PRIORITY - initp);
       named_section (NULL_TREE, buf, 0);
                  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
                        POINTER_SIZE / BITS_PER_UNIT, 1);
     }
 #endif
@@ -3310,10 +3202,13 @@ start_static_initialization_or_destruction (decl, initp)
          my_friendly_assert (initp, 20000629);
          guard_cond = get_guard_cond (guard);
        }
          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,
       else if (initp)
        guard_cond 
          = cp_build_binary_op (EQ_EXPR,
@@ -3334,9 +3229,9 @@ start_static_initialization_or_destruction (decl, initp)
 
   finish_if_stmt_cond (cond, guard_if_stmt);
 
 
   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 && flag_new_abi)
+  /* 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;
     finish_expr_stmt (set_guard (guard));
 
   return guard_if_stmt;
@@ -3381,10 +3276,6 @@ do_static_initialization (decl, init)
   if (IS_AGGR_TYPE (TREE_TYPE (decl))
       || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
     expr = build_aggr_init (decl, init, 0);
   if (IS_AGGR_TYPE (TREE_TYPE (decl))
       || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
     expr = build_aggr_init (decl, init, 0);
-  else if (TREE_CODE (init) == TREE_VEC)
-    expr = build_vec_init (decl, TREE_VEC_ELT (init, 0),
-                          TREE_VEC_ELT (init, 1),
-                          TREE_VEC_ELT (init, 2), 0);
   else
     {
       expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
   else
     {
       expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
@@ -3611,8 +3502,7 @@ finish_file ()
 
   timevar_push (TV_VARCONST);
 
 
   timevar_push (TV_VARCONST);
 
-  if (new_abi_rtti_p ())
-    emit_support_tinfos ();
+  emit_support_tinfos ();
   
   do 
     {
   
   do 
     {
@@ -3632,8 +3522,7 @@ finish_file ()
       
       /* Write out needed type info variables. Writing out one variable
          might cause others to be needed.  */
       
       /* Write out needed type info variables. Writing out one variable
          might cause others to be needed.  */
-      if (new_abi_rtti_p ()
-          && walk_globals (tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
+      if (walk_globals (tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
        reconsider = 1;
 
       /* The list of objects with static storage duration is built up
        reconsider = 1;
 
       /* The list of objects with static storage duration is built up
@@ -3706,19 +3595,12 @@ finish_file ()
                 finish_function doesn't clean things up, and we end
                 up with CURRENT_FUNCTION_DECL set.  */
              push_to_top_level ();
                 finish_function doesn't clean things up, and we end
                 up with CURRENT_FUNCTION_DECL set.  */
              push_to_top_level ();
-             if (DECL_TINFO_FN_P (decl))
-               synthesize_tinfo_fn (decl);
-             else
-               synthesize_method (decl);
+             synthesize_method (decl);
              pop_from_top_level ();
              reconsider = 1;
            }
        }
 
              pop_from_top_level ();
              reconsider = 1;
            }
        }
 
-      /* 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
       /* 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
@@ -3824,9 +3706,17 @@ finish_file ()
 
   /* The entire file is now complete.  If requested, dump everything
      to a 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)
   /* If there's some tool that wants to examine the entire translation
      unit, let it do so now.  */
   if (back_end_hook)
@@ -4027,8 +3917,8 @@ build_expr_from_tree (t)
     case ARRAY_REF:
       if (TREE_OPERAND (t, 0) == NULL_TREE)
        /* new-type-id */
     case ARRAY_REF:
       if (TREE_OPERAND (t, 0) == NULL_TREE)
        /* new-type-id */
-       return build_parse_node (ARRAY_REF, NULL_TREE,
-                                build_expr_from_tree (TREE_OPERAND (t, 1)));
+       return build_nt (ARRAY_REF, NULL_TREE,
+                        build_expr_from_tree (TREE_OPERAND (t, 1)));
       return grok_array_decl (build_expr_from_tree (TREE_OPERAND (t, 0)),
                              build_expr_from_tree (TREE_OPERAND (t, 1)));
 
       return grok_array_decl (build_expr_from_tree (TREE_OPERAND (t, 0)),
                              build_expr_from_tree (TREE_OPERAND (t, 1)));
 
@@ -4260,8 +4150,6 @@ tree
 finish_decl_parsing (decl)
      tree decl;
 {
 finish_decl_parsing (decl)
      tree decl;
 {
-  extern int current_class_depth;
-  
   switch (TREE_CODE (decl))
     {
     case IDENTIFIER_NODE:
   switch (TREE_CODE (decl))
     {
     case IDENTIFIER_NODE:
@@ -4580,6 +4468,9 @@ set_decl_namespace (decl, scope, friendp)
       if (!old)
        /* No old declaration at all. */
        goto complain;
       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
       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
@@ -4848,9 +4739,9 @@ arg_assoc_class (k, type)
           friends = TREE_CHAIN (friends))
        /* Only interested in global functions with potentially hidden
            (i.e. unqualified) declarations. */
           friends = TREE_CHAIN (friends))
        /* Only interested in global functions with potentially hidden
            (i.e. unqualified) declarations. */
-       if (TREE_PURPOSE (list) == error_mark_node && TREE_VALUE (list)
-           && decl_namespace (TREE_VALUE (list)) == context)
-         if (add_function (k, TREE_VALUE (list)))
+       if (TREE_PURPOSE (friends) == error_mark_node && TREE_VALUE (friends)
+           && decl_namespace (TREE_VALUE (friends)) == context)
+         if (add_function (k, TREE_VALUE (friends)))
            return 1;
 
   /* Process template arguments.  */
            return 1;
 
   /* Process template arguments.  */
@@ -5073,16 +4964,6 @@ validate_nonmember_using_decl (decl, scope, name)
   if (TREE_CODE (decl) == SCOPE_REF
       && TREE_OPERAND (decl, 0) == fake_std_node)
     {
   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);
     }
       *scope = global_namespace;
       *name = TREE_OPERAND (decl, 1);
     }
@@ -5095,7 +4976,8 @@ validate_nonmember_using_decl (decl, scope, name)
 
         A using-declaration for a class member shall be a
         member-declaration.  */
 
         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);
        {
          if (TYPE_P (*scope))
            cp_error ("`%T' is not a namespace", *scope);
@@ -5167,22 +5049,21 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
            {
              tree old_fn = OVL_CURRENT (tmp1);
 
            {
              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;
                }
                  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
            }
 
          /* If we broke out of the loop, there's no reason to add
@@ -5254,6 +5135,10 @@ do_local_using_decl (decl)
   if (decl == NULL_TREE)
     return;
 
   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);
 
   oldval = lookup_name_current_level (name);
   oldtype = lookup_type_current_level (name);
 
@@ -5321,18 +5206,23 @@ do_using_directive (namespace)
 {
   if (namespace == fake_std_node)
     return;
 {
   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. */
   /* 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)
     {
       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);
       return;
     }
   namespace = ORIGINAL_NAMESPACE (namespace);
@@ -5471,12 +5361,10 @@ handle_class_head (aggr, scope, id)
 void
 init_decl2 ()
 {
 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_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);
 }
 }