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,
-   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.
@@ -39,13 +39,13 @@ Boston, MA 02111-1307, USA.  */
 #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 "target.h"
 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));
 
-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.  */
@@ -131,23 +126,9 @@ 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.  */
 
-/* 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;
@@ -213,10 +194,7 @@ int warn_ctor_dtor_privacy = 1;
 /* 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.  */
@@ -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.  */
+
 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.  */
+
 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_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;
 
-/* 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.  */   
-/* 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.  */
 
@@ -370,11 +341,8 @@ int flag_default_inline = 1;
 
 /* 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.  */
@@ -416,10 +384,6 @@ int flag_new_for_scope = 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.  */
 
@@ -427,31 +391,20 @@ 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;
 
-/* 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.  */
 
@@ -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},
-  {"cond-mismatch", &flag_cond_mismatch, 1},
   {"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},
-  {"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},
@@ -520,13 +470,10 @@ lang_f_options[] =
   {"permissive", &flag_permissive, 1},
   {"repo", &flag_use_repository, 1},
   {"rtti", &flag_rtti, 1},
-  {"squangle", &flag_do_squangling, 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'
@@ -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",
+  "cond-mismatch",
   "enum-int-equiv",
   "guiding-decls",
+  "huge-objects",
+  "labels-ok",
+  "new-abi",
   "nonnull-objects",
-  "this-is-variable",
+  "squangle",
   "strict-prototype",
+  "this-is-variable",
+  "vtable-thunks",
+  "xref"
 };
 
 /* 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   
-lang_decode_option (argc, argv)
+cxx_decode_option (argc, argv)
      int argc;
      char **argv;
 {
@@ -623,33 +577,18 @@ lang_decode_option (argc, argv)
           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-")))
-       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;
@@ -720,12 +659,16 @@ lang_decode_option (argc, argv)
        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-security"))
+       warn_format_security = setting;
       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;
-      else if (!strcmp (p, "extern-inline"))
-       warn_extern_inline = setting;
       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;
+  /* All our artificial parms are implicitly `const'; they cannot be
+     assigned to.  */
+  TREE_READONLY (parm) = 1;
   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.
-   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)
@@ -961,17 +908,38 @@ maybe_retrofit_in_chrg (fn)
       && !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 = 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)))
@@ -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;
-
-  /* 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.
@@ -1026,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)
     {
@@ -1064,22 +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;
-
-      if (flag_new_abi) 
-       set_mangled_name_for_decl (function);
-      else
-       DECL_ASSEMBLER_NAME (function) = build_destructor_name (ctype);
-
       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).  */
@@ -1335,7 +1286,7 @@ acceptable_java_type (type)
 {
   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)
@@ -1444,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 
@@ -1533,28 +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;
-      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)
@@ -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;
       
-      /* 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);
 
@@ -1779,15 +1691,10 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
   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;
-      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;
@@ -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.  */
-         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);
 
@@ -1880,10 +1787,7 @@ grokoptypename (declspecs, declarator)
      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,
@@ -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 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)
        {
@@ -1997,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));
@@ -2193,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)
@@ -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);
 
+  /* 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;
 
@@ -2231,8 +2118,8 @@ finish_anon_union (anon_union_decl)
 
   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));
@@ -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
-          virtual call offset, and RTTI offset, etc.  */
+          virtual call offset, an RTTI offset, etc.  */
        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)) 
-       use_thunk (fn, THUNK_GENERATE_WITH_VTABLE_P (fn));
+       use_thunk (fn, /*emit_p=*/0);
       mark_used (fn);
     }
 }
@@ -2393,14 +2280,24 @@ comdat_linkage (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
-       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
     {
@@ -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. */
-  if (! supports_one_only ())
+  if (! flag_weak)
     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
-       && ! 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;
@@ -2502,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
@@ -2554,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.  */
@@ -2587,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);
     }
 }
@@ -2672,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);
@@ -2724,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 
@@ -2738,28 +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)
-         && (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 if (DECL_TINFO_FN_P (decl))
+  else if (tinfo_decl_p (decl, 0))
     {
       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_THIS_INLINE (decl) && ! flag_implement_inlines
+                || (DECL_DECLARED_INLINE_P (decl) 
+                    && ! flag_implement_inlines
                     && !DECL_VINDEX (decl)));
 
          /* Always make artificials weak.  */
@@ -2830,23 +2739,7 @@ get_guard (decl)
   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)
     {
@@ -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.  */
-      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);
-      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;
-      TREE_STATIC (guard) = 1;
       TREE_USED (guard) = 1;
-      DECL_COMMON (guard) = 1;
       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;
 {
-  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, 
@@ -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);
-      assemble_integer (gen_rtx_SYMBOL_REF (Pmode, fnname),
+      assemble_integer (XEXP (DECL_RTL (fn), 0),
                        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);
        }
-      /* 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,
@@ -3334,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 && 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;
@@ -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);
-  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);
@@ -3611,8 +3502,7 @@ finish_file ()
 
   timevar_push (TV_VARCONST);
 
-  if (new_abi_rtti_p ())
-    emit_support_tinfos ();
+  emit_support_tinfos ();
   
   do 
     {
@@ -3632,8 +3522,7 @@ finish_file ()
       
       /* 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
@@ -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 ();
-             if (DECL_TINFO_FN_P (decl))
-               synthesize_tinfo_fn (decl);
-             else
-               synthesize_method (decl);
+             synthesize_method (decl);
              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
@@ -3824,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)
@@ -4027,8 +3917,8 @@ build_expr_from_tree (t)
     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)));
 
@@ -4260,8 +4150,6 @@ tree
 finish_decl_parsing (decl)
      tree decl;
 {
-  extern int current_class_depth;
-  
   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;
+      /* 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
@@ -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. */
-       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.  */
@@ -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 (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);
     }
@@ -5095,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);
@@ -5167,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
@@ -5254,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);
 
@@ -5321,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);
@@ -5471,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);
 }