Do put the VTT parameter in DECL_ARGUMENTS.
authorJason Merrill <jason@redhat.com>
Sun, 18 Feb 2001 19:08:00 +0000 (14:08 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 18 Feb 2001 19:08:00 +0000 (14:08 -0500)
        * cp-tree.h (struct cp_language_function): Add x_vtt_parm.
        (current_vtt_parm): New macro.
        (struct lang_decl_flags): Add has_vtt_parm_p, remove vtt_parm.
        (DECL_HAS_VTT_PARM_P): New macro.
        (DECL_VTT_PARM): Remove.
        (FUNCTION_FIRST_USER_PARMTYPE, FUNCTION_FIRST_USER_PARM): New macros.
        * decl.c (duplicate_decls): Only copy the operator code if
        appropriate.
        (start_function): Set current_vtt_parm.
        (lang_mark_tree): Don't mark vtt_parm.
        * decl2.c (maybe_retrofit_in_chrg): Do add the VTT parm to
        DECL_ARGUMENTS.  Set DECL_HAS_VTT_PARM_P.
        * class.c (build_clone): Maybe remove the VTT parm.
        * optimize.c (maybe_clone_body): Set up the VTT parm.
        * pt.c (copy_default_args_to_explicit_spec): Preserve the VTT parm.
        * call.c (build_over_call): Just allow the VTT arg.
        * method.c (make_thunk): Don't set DECL_VTT_PARM.
        (do_build_copy_constructor): Use FUNCTION_FIRST_USER_PARM.
        (synthesize_method): Use FUNCTION_FIRST_USER_PARMTYPE.
        * decl.c (grokdeclarator, copy_args_p, grok_ctor_properties): Likewise.
        * error.c (dump_function_decl): Likewise.
        * call.c (build_user_type_conversion_1, convert_like_real): Abort
        if we try to call a constructor with in-charge or VTT parms.
        * method.c (skip_artificial_parms_for): New fn.
        * call.c (add_function_candidate, build_over_call): Call it.
        * call.c (build_new_method_call): Use current_vtt_parm.
        * init.c (expand_virtual_init): Likewise.
        * class.c (same_signature_p): No longer static.
        * cp-tree.h: Declare it.
        * search.c (look_for_overrides_r): Use it.

From-SVN: r39841

12 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/optimize.c
gcc/cp/pt.c
gcc/cp/search.c

index 99dfb5052f87b2d645d5a4bc0cb38181cf580156..b94cd78b4ad99c5a4e8b16d347ab751529b8c8f0 100644 (file)
@@ -1,3 +1,37 @@
+2001-02-18  Jason Merrill  <jason@redhat.com>
+
+       Do put the VTT parameter in DECL_ARGUMENTS.
+       * cp-tree.h (struct cp_language_function): Add x_vtt_parm.
+       (current_vtt_parm): New macro.
+       (struct lang_decl_flags): Add has_vtt_parm_p, remove vtt_parm.
+       (DECL_HAS_VTT_PARM_P): New macro.
+       (DECL_VTT_PARM): Remove.
+       (FUNCTION_FIRST_USER_PARMTYPE, FUNCTION_FIRST_USER_PARM): New macros.
+       * decl.c (duplicate_decls): Only copy the operator code if
+       appropriate.
+       (start_function): Set current_vtt_parm.
+       (lang_mark_tree): Don't mark vtt_parm.
+       * decl2.c (maybe_retrofit_in_chrg): Do add the VTT parm to 
+       DECL_ARGUMENTS.  Set DECL_HAS_VTT_PARM_P.
+       * class.c (build_clone): Maybe remove the VTT parm.
+       * optimize.c (maybe_clone_body): Set up the VTT parm.
+       * pt.c (copy_default_args_to_explicit_spec): Preserve the VTT parm.
+       * call.c (build_over_call): Just allow the VTT arg.
+       * method.c (make_thunk): Don't set DECL_VTT_PARM.
+       (do_build_copy_constructor): Use FUNCTION_FIRST_USER_PARM.
+       (synthesize_method): Use FUNCTION_FIRST_USER_PARMTYPE.
+       * decl.c (grokdeclarator, copy_args_p, grok_ctor_properties): Likewise.
+       * error.c (dump_function_decl): Likewise.
+       * call.c (build_user_type_conversion_1, convert_like_real): Abort
+       if we try to call a constructor with in-charge or VTT parms.
+       * method.c (skip_artificial_parms_for): New fn.
+       * call.c (add_function_candidate, build_over_call): Call it.
+       * call.c (build_new_method_call): Use current_vtt_parm.
+       * init.c (expand_virtual_init): Likewise.
+       * class.c (same_signature_p): No longer static.
+       * cp-tree.h: Declare it.
+       * search.c (look_for_overrides_r): Use it.
+
 2001-02-17  Mark Mitchell  <mark@codesourcery.com>
 
        * init.c (build_new): Allow enumeration types for the array-bounds
index 184ffeb64667bfd29e81f7cc97c0bbb43d66f387..b7e6e943c6b71ff5945d1355869fb2dd2a7a7588 100644 (file)
@@ -1305,17 +1305,12 @@ add_function_candidate (candidates, fn, ctype, arglist, flags)
   tree parmnode, argnode;
   int viable = 1;
 
-  /* The `this' and `in_chrg' arguments to constructors are not considered
-     in overload resolution.  */
+  /* The `this', `in_chrg' and VTT arguments to constructors are not
+     considered in overload resolution.  */
   if (DECL_CONSTRUCTOR_P (fn))
     {
-      parmlist = TREE_CHAIN (parmlist);
-      arglist = TREE_CHAIN (arglist);
-      if (DECL_HAS_IN_CHARGE_PARM_P (fn))
-       {
-         parmlist = TREE_CHAIN (parmlist);
-         arglist = TREE_CHAIN (arglist);
-       }
+      parmlist = skip_artificial_parms_for (fn, parmlist);
+      arglist = skip_artificial_parms_for (fn, arglist);
     }
 
   len = list_length (arglist);
@@ -2382,10 +2377,11 @@ build_user_type_conversion_1 (totype, expr, flags)
       t = build_int_2 (0, 0);
       TREE_TYPE (t) = build_pointer_type (totype);
       args = build_tree_list (NULL_TREE, expr);
-      if (DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors)))
-       args = tree_cons (NULL_TREE, 
-                         in_charge_arg_for_name (complete_ctor_identifier), 
-                         args);
+      if (DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))
+         || DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors)))
+       /* We should never try to call the abstract or base constructor
+          from here.  */
+       abort ();
       args = tree_cons (NULL_TREE, t, args);
     }
   for (; ctors; ctors = OVL_NEXT (ctors))
@@ -3735,8 +3731,11 @@ convert_like_real (convs, expr, fn, argnum, inner)
            TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (convfn));
 
            args = build_tree_list (NULL_TREE, expr);
-           if (DECL_HAS_IN_CHARGE_PARM_P (convfn))
-             args = tree_cons (NULL_TREE, integer_one_node, args);
+           if (DECL_HAS_IN_CHARGE_PARM_P (convfn)
+               || DECL_HAS_VTT_PARM_P (convfn))
+             /* We should never try to call the abstract or base constructor
+                from here.  */
+             abort ();
            args = tree_cons (NULL_TREE, t, args);
          }
        else
@@ -4065,6 +4064,9 @@ build_over_call (cand, args, flags)
       arg = TREE_CHAIN (arg);
       parm = TREE_CHAIN (parm);
       if (DECL_HAS_IN_CHARGE_PARM_P (fn))
+       /* We should never try to call the abstract constructor.  */
+       abort ();
+      if (DECL_HAS_VTT_PARM_P (fn))
        {
          converted_args = tree_cons
            (NULL_TREE, TREE_VALUE (arg), converted_args);
@@ -4169,9 +4171,7 @@ build_over_call (cand, args, flags)
           && DECL_COPY_CONSTRUCTOR_P (fn))
     {
       tree targ;
-      arg = TREE_CHAIN (converted_args);
-      if (DECL_HAS_IN_CHARGE_PARM_P (fn))
-       arg = TREE_CHAIN (arg);
+      arg = skip_artificial_parms_for (fn, converted_args);
       arg = TREE_VALUE (arg);
 
       /* Pull out the real argument, disregarding const-correctness.  */
@@ -4439,7 +4439,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
          vtt = build (COND_EXPR, TREE_TYPE (vtt),
                       build (EQ_EXPR, boolean_type_node,
                              current_in_charge_parm, integer_zero_node),
-                      DECL_VTT_PARM (current_function_decl),
+                      current_vtt_parm,
                       vtt);
          if (TREE_VIA_VIRTUAL (basebinfo))
            basebinfo = binfo_for_vbase (basetype, current_class_type);
index 55bac3711ea0631a7b3699c3166d0b5bf0c5969e..7c2102101b3235f3922759fd59622ffe828aad49 100644 (file)
@@ -119,7 +119,6 @@ static void delete_duplicate_fields PARAMS ((tree));
 static void finish_struct_bits PARAMS ((tree));
 static int alter_access PARAMS ((tree, tree, tree));
 static void handle_using_decl PARAMS ((tree, tree));
-static int same_signature_p PARAMS ((tree, tree));
 static int strictly_overrides PARAMS ((tree, tree));
 static void mark_overriders PARAMS ((tree, tree));
 static void check_for_override PARAMS ((tree, tree));
@@ -2460,7 +2459,7 @@ layout_vtable_decl (binfo, n)
 /* True iff FNDECL and BASE_FNDECL (both non-static member functions)
    have the same signature.  */
 
-static int
+int
 same_signature_p (fndecl, base_fndecl)
      tree fndecl, base_fndecl;
 {
@@ -4188,8 +4187,6 @@ build_clone (fn, name)
   DECL_PENDING_INLINE_P (clone) = 0;
   /* And it hasn't yet been deferred.  */
   DECL_DEFERRED_FN (clone) = 0;
-  /* There's no magic VTT parameter in the clone.  */
-  DECL_VTT_PARM (clone) = NULL_TREE;
 
   /* The base-class destructor is not virtual.  */
   if (name == base_dtor_identifier)
@@ -4214,10 +4211,12 @@ build_clone (fn, name)
       parmtypes = TREE_CHAIN (parmtypes);
       /* Skip the in-charge parameter.  */
       parmtypes = TREE_CHAIN (parmtypes);
+      /* And the VTT parm, in a complete [cd]tor.  */
+      if (DECL_HAS_VTT_PARM_P (fn)
+         && ! DECL_NEEDS_VTT_PARM_P (clone))
+       parmtypes = TREE_CHAIN (parmtypes);
        /* If this is subobject constructor or destructor, add the vtt
         parameter.  */
-      if (DECL_NEEDS_VTT_PARM_P (clone))
-       parmtypes = hash_tree_chain (vtt_parm_type, parmtypes);
       TREE_TYPE (clone) 
        = build_cplus_method_type (basetype,
                                   TREE_TYPE (TREE_TYPE (clone)),
@@ -4227,8 +4226,8 @@ build_clone (fn, name)
                                                     exceptions);
     }
 
-  /* Copy the function parameters.  But, DECL_ARGUMENTS aren't
-     function parameters; instead, those are the template parameters.  */
+  /* Copy the function parameters.  But, DECL_ARGUMENTS on a TEMPLATE_DECL
+     aren't function parameters; those are the template parameters.  */
   if (TREE_CODE (clone) != TEMPLATE_DECL)
     {
       DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
@@ -4239,16 +4238,17 @@ build_clone (fn, name)
            = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
          DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
        }
-
-      /* Add the VTT parameter.  */
-      if (DECL_NEEDS_VTT_PARM_P (clone))
+      /* And the VTT parm, in a complete [cd]tor.  */
+      if (DECL_HAS_VTT_PARM_P (fn))
        {
-         tree parm;
-
-         parm = build_artificial_parm (vtt_parm_identifier,
-                                       vtt_parm_type);
-         TREE_CHAIN (parm) = TREE_CHAIN (DECL_ARGUMENTS (clone));
-         TREE_CHAIN (DECL_ARGUMENTS (clone)) = parm;
+         if (DECL_NEEDS_VTT_PARM_P (clone))
+           DECL_HAS_VTT_PARM_P (clone) = 1;
+         else
+           {
+             TREE_CHAIN (DECL_ARGUMENTS (clone))
+               = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
+             DECL_HAS_VTT_PARM_P (clone) = 0;
+           }
        }
 
       for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
index f35dd95ce8fa748683e6b8d53fc522c87a8c712b..f7ed02c9990651dd9a106419d68e9d7e358d2cd4 100644 (file)
@@ -881,6 +881,7 @@ struct cp_language_function
   tree x_current_class_ref;
   tree x_eh_spec_try_block;
   tree x_in_charge_parm;
+  tree x_vtt_parm;
 
   tree *x_vcalls_possible_p;
 
@@ -927,10 +928,15 @@ struct cp_language_function
 #define current_eh_spec_try_block cp_function_chain->x_eh_spec_try_block
 
 /* The `__in_chrg' parameter for the current function.  Only used for
-   destructors.  */
+   constructors and destructors.  */
 
 #define current_in_charge_parm cp_function_chain->x_in_charge_parm
 
+/* The `__vtt_parm' parameter for the current function.  Only used for
+   constructors and destructors.  */
+
+#define current_vtt_parm cp_function_chain->x_vtt_parm
+
 /* In destructors, this is a pointer to a condition in an
    if-statement.  If the pointed-to value is boolean_true_node, then
    there may be virtual function calls in this destructor.  */
@@ -1249,7 +1255,18 @@ enum languages { lang_c, lang_cplusplus, lang_java };
    ? (ENTRY)                                                           \
    : DECL_INITIAL (TREE_OPERAND ((ENTRY), 0)))
 
-#define FUNCTION_ARG_CHAIN(NODE) (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))))
+#define FUNCTION_ARG_CHAIN(NODE) \
+  (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))))
+
+/* Given a FUNCTION_DECL, returns the first TREE_LIST out of TYPE_ARG_TYPES
+   which refers to a user-written parameter.  */
+#define FUNCTION_FIRST_USER_PARMTYPE(NODE) \
+  (skip_artificial_parms_for (NODE, TYPE_ARG_TYPES (TREE_TYPE (NODE))))
+
+/* Similarly, but for DECL_ARGUMENTS.  */
+#define FUNCTION_FIRST_USER_PARM(NODE) \
+  (skip_artificial_parms_for (NODE, DECL_ARGUMENTS (NODE)))
+
 #define PROMOTES_TO_AGGR_TYPE(NODE,CODE)       \
   (((CODE) == TREE_CODE (NODE)                 \
        && IS_AGGR_TYPE (TREE_TYPE (NODE)))     \
@@ -1825,7 +1842,7 @@ struct lang_decl_flags
   unsigned assignment_operator_p : 1;
   unsigned anticipated_p : 1;
   unsigned generate_with_vtable_p : 1;
-  unsigned dummy : 1;
+  unsigned has_vtt_parm_p : 1;
 
   union {
     /* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this
@@ -1876,9 +1893,6 @@ struct lang_decl
     /* In an overloaded operator, this is the value of
        DECL_OVERLOADED_OPERATOR_P.  */
     enum tree_code operator_code;
-    /* In a maybe-in-charge constructor or destructor, this is
-       DECL_VTT_PARM.  */
-    tree vtt_parm;
   } u2;
 };
 
@@ -1978,10 +1992,9 @@ struct lang_decl
 #define DECL_CLONED_FUNCTION(NODE) \
   (DECL_LANG_SPECIFIC (NODE)->cloned_function)
 
-/* In a maybe-in-charge constructor or destructor, this is the VTT
-   parameter.  It's not actually on the DECL_ARGUMENTS list.  */
-#define DECL_VTT_PARM(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->u2.vtt_parm)
+/* Non-zero if the VTT parm has been added to NODE.  */
+#define DECL_HAS_VTT_PARM_P(NODE) \
+  (DECL_LANG_SPECIFIC (NODE)->decl_flags.has_vtt_parm_p)
 
 /* Non-zero if NODE is a FUNCTION_DECL for which a VTT parameter is
    required.  */
@@ -3723,6 +3736,7 @@ extern void pop_lang_context                      PARAMS ((void));
 extern tree instantiate_type                   PARAMS ((tree, tree, enum instantiate_type_flags));
 extern void print_class_statistics             PARAMS ((void));
 extern void build_self_reference               PARAMS ((void));
+extern int same_signature_p                    PARAMS ((tree, tree));
 extern void warn_hidden                                PARAMS ((tree));
 extern tree get_enclosing_class                        PARAMS ((tree));
 int is_base_of_enclosing_class                 PARAMS ((tree, tree));
@@ -4085,6 +4099,7 @@ extern tree make_thunk                            PARAMS ((tree, tree, tree, int));
 extern void use_thunk                          PARAMS ((tree, int));
 extern void synthesize_method                  PARAMS ((tree));
 extern tree implicitly_declare_fn               PARAMS ((special_function_kind, tree, int));
+extern tree skip_artificial_parms_for          PARAMS ((tree, tree));
 
 /* In optimize.c */
 extern void optimize_function                   PARAMS ((tree));
index 4e727ad94b9719973db3ace22338e3ef8dbf67cb..3b38d68c98712756a6f1557473db5ed2285b3a94 100644 (file)
@@ -3399,7 +3399,9 @@ duplicate_decls (newdecl, olddecl)
       DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
       DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
       DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
-      DECL_LANG_SPECIFIC (newdecl)->u2 = DECL_LANG_SPECIFIC (olddecl)->u2;
+      if (DECL_OVERLOADED_OPERATOR_P (olddecl) != ERROR_MARK)
+       SET_OVERLOADED_OPERATOR_CODE
+         (newdecl, DECL_OVERLOADED_OPERATOR_P (olddecl));
       new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
 
       /* Optionally warn about more than one declaration for the same
@@ -11300,15 +11302,8 @@ friend declaration requires class-key, i.e. `friend %#T'",
                /* The constructor can be called with exactly one
                   parameter if there is at least one parameter, and
                   any subsequent parameters have default arguments.
-                  We don't look at the first parameter, which is
-                  really just the `this' parameter for the new
-                  object.  */
-               tree arg_types =
-                 TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)));
-
-               /* Skip the `in_chrg' argument too, if present.  */
-               if (DECL_HAS_IN_CHARGE_PARM_P (decl))
-                 arg_types = TREE_CHAIN (arg_types);
+                  Ignore any compiler-added parms.  */
+               tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (decl);
 
                if (arg_types == void_list_node
                    || (arg_types
@@ -11923,9 +11918,7 @@ copy_args_p (d)
   if (!DECL_FUNCTION_MEMBER_P (d))
     return 0;
 
-  t = FUNCTION_ARG_CHAIN (d);
-  if (DECL_CONSTRUCTOR_P (d) && DECL_HAS_IN_CHARGE_PARM_P (d))
-    t = TREE_CHAIN (t);
+  t = FUNCTION_FIRST_USER_PARMTYPE (d);
   if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
       && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
          == DECL_CONTEXT (d))
@@ -11948,22 +11941,9 @@ int
 grok_ctor_properties (ctype, decl)
      tree ctype, decl;
 {
-  tree parmtypes = FUNCTION_ARG_CHAIN (decl);
+  tree parmtypes = FUNCTION_FIRST_USER_PARMTYPE (decl);
   tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
 
-  /* When a type has virtual baseclasses, a magical first int argument is
-     added to any ctor so we can tell if the class has been initialized
-     yet.  This could screw things up in this function, so we deliberately
-     ignore the leading int if we're in that situation.  */
-  if (DECL_HAS_IN_CHARGE_PARM_P (decl))
-    {
-      my_friendly_assert (parmtypes
-                         && TREE_VALUE (parmtypes) == integer_type_node,
-                         980529);
-      parmtypes = TREE_CHAIN (parmtypes);
-      parmtype = TREE_VALUE (parmtypes);
-    }
-
   /* [class.copy]
 
      A non-template constructor for class X is a copy constructor if
@@ -13473,8 +13453,18 @@ start_function (declspecs, declarator, attrs, flags)
 
       /* Constructors and destructors need to know whether they're "in
         charge" of initializing virtual base classes.  */
+      t = TREE_CHAIN (t);
       if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
-       current_in_charge_parm = TREE_CHAIN (t);
+       {
+         current_in_charge_parm = t;
+         t = TREE_CHAIN (t);
+       }
+      if (DECL_HAS_VTT_PARM_P (decl1))
+       {
+         if (DECL_NAME (t) != vtt_parm_identifier)
+           abort ();
+         current_vtt_parm = t;
+       }
     }
 
   if (DECL_INTERFACE_KNOWN (decl1))
@@ -14425,8 +14415,6 @@ lang_mark_tree (t)
              ggc_mark_tree (ld->befriending_classes);
              ggc_mark_tree (ld->context);
              ggc_mark_tree (ld->cloned_function);
-             if (!DECL_OVERLOADED_OPERATOR_P (t))
-               ggc_mark_tree (ld->u2.vtt_parm);
              if (TREE_CODE (t) == TYPE_DECL)
                ggc_mark_tree (ld->u.sorted_fields);
              else if (TREE_CODE (t) == FUNCTION_DECL
index 20aa6a82d726bddd8a97be17479f20575efa7534..37e6d4ad692d5ac7c2e3e041f76eff099d954ad1 100644 (file)
@@ -932,7 +932,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)
@@ -955,17 +958,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)))
@@ -975,15 +999,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 (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;
-    }
 }
 
 /* Classes overload their constituent function names automatically.
index 30912362f08d0f360165f5f7398eaafaa9a6a2f3..0ec740532dc9ada4686a08fd358088605f39b2e5 100644 (file)
@@ -1203,7 +1203,7 @@ dump_function_decl (t, flags)
     }
 
   fntype = TREE_TYPE (t);
-  parmtypes = TYPE_ARG_TYPES (fntype);
+  parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
 
   if (DECL_CLASS_SCOPE_P (t))
     cname = DECL_CONTEXT (t);
@@ -1241,14 +1241,6 @@ dump_function_decl (t, flags)
 
   if (flags & TFF_DECL_SPECIFIERS) 
     {
-      if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
-       /* Skip "this" parameter.  */
-       parmtypes = TREE_CHAIN (parmtypes);
-
-      /* Skip past the "in_charge" parameter.  */
-      if (DECL_HAS_IN_CHARGE_PARM_P (t))
-       parmtypes = TREE_CHAIN (parmtypes);
-
       dump_parameters (parmtypes, flags);
 
       if (show_return)
index 68139d8d577d798224562333e937aeba87d50e55..4d498aa9e96ba110c5c6e3845b3373c4d5ec687a 100644 (file)
@@ -860,7 +860,7 @@ expand_virtual_init (binfo, decl)
       tree vtt_parm;
 
       /* Compute the value to use, when there's a VTT.  */
-      vtt_parm = DECL_VTT_PARM (current_function_decl);
+      vtt_parm = current_vtt_parm;
       vtbl2 = build (PLUS_EXPR, 
                     TREE_TYPE (vtt_parm), 
                     vtt_parm,
index ccaec60424fdbb9e6aa17ae7529e01733566e7cf..349afcbb60badd58c7e44c802365bc8f54375650 100644 (file)
@@ -364,7 +364,6 @@ make_thunk (function, delta, vcall_index, generate_with_vtable_p)
       DECL_CONSTRUCTOR_P (thunk) = 0;
       DECL_EXTERNAL (thunk) = 1;
       DECL_ARTIFICIAL (thunk) = 1;
-      DECL_VTT_PARM (thunk) = NULL_TREE;
       /* Even if this thunk is a member of a local class, we don't
         need a static chain.  */
       DECL_NO_STATIC_CHAIN (thunk) = 1;
@@ -536,11 +535,9 @@ static void
 do_build_copy_constructor (fndecl)
      tree fndecl;
 {
-  tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
+  tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
   tree t;
 
-  if (DECL_HAS_IN_CHARGE_PARM_P (fndecl))
-    parm = TREE_CHAIN (parm);
   parm = convert_from_reference (parm);
 
   if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)
@@ -760,9 +757,7 @@ synthesize_method (fndecl)
     setup_vtbl_ptr (NULL_TREE, NULL_TREE);
   else
     {
-      tree arg_chain = FUNCTION_ARG_CHAIN (fndecl);
-      if (DECL_HAS_IN_CHARGE_PARM_P (fndecl))
-       arg_chain = TREE_CHAIN (arg_chain);
+      tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
       if (arg_chain != void_list_node)
        do_build_copy_constructor (fndecl);
       else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))
@@ -1041,3 +1036,22 @@ implicitly_declare_fn (kind, type, const_p)
   
   return fn;
 }
+
+/* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
+   as there are artificial parms in FN.  */
+
+tree
+skip_artificial_parms_for (fn, list)
+     tree fn, list;
+{
+  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+    list = TREE_CHAIN (list);
+  else
+    return list;
+
+  if (DECL_HAS_IN_CHARGE_PARM_P (fn))
+    list = TREE_CHAIN (list);
+  if (DECL_HAS_VTT_PARM_P (fn))
+    list = TREE_CHAIN (list);
+  return list;
+}
index 442cac0d5511f07f180bcd5058bab96729f15550..9d700f60904c6f777db28ba41d64f818d60256b3 100644 (file)
@@ -981,22 +981,25 @@ maybe_clone_body (fn)
              splay_tree_insert (id.decl_map,
                                 (splay_tree_key) parm,
                                 (splay_tree_value) in_charge);
-
+           }
+         else if (DECL_ARTIFICIAL (parm)
+                  && DECL_NAME (parm) == vtt_parm_identifier)
+           {
              /* For a subobject constructor or destructor, the next
                 argument is the VTT parameter.  Remap the VTT_PARM
                 from the CLONE to this parameter.  */
-             if (DECL_NEEDS_VTT_PARM_P (clone))
+             if (DECL_HAS_VTT_PARM_P (clone))
                {
                  splay_tree_insert (id.decl_map,
-                                    (splay_tree_key) DECL_VTT_PARM (fn),
+                                    (splay_tree_key) parm,
                                     (splay_tree_value) clone_parm);
                  clone_parm = TREE_CHAIN (clone_parm);
                }
              /* Otherwise, map the VTT parameter to `NULL'.  */
-             else if (DECL_VTT_PARM (fn))
+             else
                {
                  splay_tree_insert (id.decl_map,
-                                    (splay_tree_key) DECL_VTT_PARM (fn),
+                                    (splay_tree_key) parm,
                                     (splay_tree_value) null_pointer_node);
                }
            }
index b28c60a2b5b2677a30c369940d4acaff84fa7cc2..ab420b55379e3cbad2eb7c5f6a9fd7926e5fc2a7 100644 (file)
@@ -1208,6 +1208,7 @@ copy_default_args_to_explicit_spec (decl)
   tree t;
   tree object_type = NULL_TREE;
   tree in_charge = NULL_TREE;
+  tree vtt = NULL_TREE;
 
   /* See if there's anything we need to do.  */
   tmpl = DECL_TI_TEMPLATE (decl);
@@ -1236,6 +1237,11 @@ copy_default_args_to_explicit_spec (decl)
           in_charge = spec_types;
          spec_types = TREE_CHAIN (spec_types);
        }
+      if (DECL_HAS_VTT_PARM_P (decl))
+       {
+         vtt = spec_types;
+         spec_types = TREE_CHAIN (spec_types);
+       }
     }
 
   /* Compute the merged default arguments.  */
@@ -1245,6 +1251,11 @@ copy_default_args_to_explicit_spec (decl)
   /* Compute the new FUNCTION_TYPE.  */
   if (object_type)
     {
+      if (vtt)
+        new_spec_types = hash_tree_cons (TREE_PURPOSE (vtt),
+                                        TREE_VALUE (vtt),
+                                        new_spec_types);
+
       if (in_charge)
         /* Put the in-charge parameter back.  */
         new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),
index 75d33e8e40bcfd936cd965edfa20e5a6ebb3b061..6b13469da94c71cb22a540170362f9873a201e05 100644 (file)
@@ -2046,22 +2046,13 @@ look_for_overrides_r (type, fndecl)
                   return 1;
                 }
             }
-          else
+          else if (same_signature_p (fndecl, fn))
             {
-              if (/* The first parameter is the `this' parameter,
-                    which has POINTER_TYPE, and we can therefore
-                    safely use TYPE_QUALS, rather than
-                    CP_TYPE_QUALS.  */
-                 (TYPE_QUALS (TREE_TYPE (TREE_VALUE (btypes)))
-                  == TYPE_QUALS (thistype))
-                 && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes)))
-                {
-                  /* It's definitely virtual, even if not explicitly set.  */
-                  DECL_VIRTUAL_P (fndecl) = 1;
-                 check_final_overrider (fndecl, fn);
-             
-                 return 1;
-               }
+             /* It's definitely virtual, even if not explicitly set.  */
+             DECL_VIRTUAL_P (fndecl) = 1;
+             check_final_overrider (fndecl, fn);
+
+             return 1;
            }
        }
     }