OSDN Git Service

* cp-tree.h (enum cp_tree_index): Add CPTI_PFN_VFLAG_IDENTIFIER.
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 4 May 2001 06:28:54 +0000 (06:28 +0000)
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 4 May 2001 06:28:54 +0000 (06:28 +0000)
(pfn_vflag_identifier): Define.
Update comment about layout of pointer functions.
(build_ptrmemfunc1): Update prototype.
(expand_ptrmemfunc_cst): Update prototype.
* decl.c (initialize_predefined_identifiers): Initialize
pfn_vflag_identifier.
(build_ptrmemfunc_type): When FUNCTION_BOUNDARY < 16, add
an extra field to the type.
* expr.c (cplus_expand_constant): Pass 'flag' between
expand_ptrmemfunc_cst and build_ptrmemfunc1.
* typeck.c (get_member_function_from_ptrfunc): When
FUNCTION_BOUNDARY < 16, look at additional field to determine
if a pointer-to-member is a real pointer or a vtable offset.
(build_ptrmemfunc1): Add new parameter to contain extra field.
(build_ptrmemfunc): Pass the extra field around.
(expand_ptrmemfunc_cst): Add new parameter to return extra field.
(pfn_from_ptrmemfunc): Ignore the extra field.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41824 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/expr.c
gcc/cp/typeck.c

index 0acfdb9..9030ae6 100644 (file)
@@ -1,3 +1,24 @@
+2001-05-03  Geoffrey Keating  <geoffk@redhat.com>
+
+       * cp-tree.h (enum cp_tree_index): Add CPTI_PFN_VFLAG_IDENTIFIER.
+       (pfn_vflag_identifier): Define.
+       Update comment about layout of pointer functions.
+       (build_ptrmemfunc1): Update prototype.
+       (expand_ptrmemfunc_cst): Update prototype.
+       * decl.c (initialize_predefined_identifiers): Initialize
+       pfn_vflag_identifier.
+       (build_ptrmemfunc_type): When FUNCTION_BOUNDARY < 16, add
+       an extra field to the type.
+       * expr.c (cplus_expand_constant): Pass 'flag' between 
+       expand_ptrmemfunc_cst and build_ptrmemfunc1.
+       * typeck.c (get_member_function_from_ptrfunc): When
+       FUNCTION_BOUNDARY < 16, look at additional field to determine
+       if a pointer-to-member is a real pointer or a vtable offset.
+       (build_ptrmemfunc1): Add new parameter to contain extra field.
+       (build_ptrmemfunc): Pass the extra field around.
+       (expand_ptrmemfunc_cst): Add new parameter to return extra field.
+       (pfn_from_ptrmemfunc): Ignore the extra field.
+
 2001-05-03  Mark Mitchell  <mark@codesourcery.com>
 
        * cp-tree.h (flag_inline_trees): Update documentation.
index 05a0d0f..e1b9361 100644 (file)
@@ -611,6 +611,7 @@ enum cp_tree_index
     CPTI_NELTS_IDENTIFIER,
     CPTI_THIS_IDENTIFIER,
     CPTI_PFN_IDENTIFIER,
+    CPTI_PFN_VFLAG_IDENTIFIER,
     CPTI_PFN_OR_DELTA2_IDENTIFIER,
     CPTI_VPTR_IDENTIFIER,
     CPTI_STD_IDENTIFIER,
@@ -735,6 +736,7 @@ extern tree cp_global_trees[CPTI_MAX];
 #define nelts_identifier                cp_global_trees[CPTI_NELTS_IDENTIFIER]
 #define this_identifier                 cp_global_trees[CPTI_THIS_IDENTIFIER]
 #define pfn_identifier                  cp_global_trees[CPTI_PFN_IDENTIFIER]
+#define pfn_vflag_identifier            cp_global_trees[CPTI_PFN_VFLAG_IDENTIFIER]
 #define pfn_or_delta2_identifier        cp_global_trees[CPTI_PFN_OR_DELTA2_IDENTIFIER]
 #define vptr_identifier                 cp_global_trees[CPTI_VPTR_IDENTIFIER]
 /* The name of the std namespace.  */
@@ -2618,29 +2620,27 @@ extern int flag_new_for_scope;
 /* A pointer-to-function member type looks like:
 
    struct {
-     short __delta;
-     short __index;
-     union {
-       P __pfn;
-       short __delta2;
-     } __pfn_or_delta2;
+     __P __pfn;
+     ptrdiff_t __delta;
    };
 
-   where P is a POINTER_TYPE to a METHOD_TYPE appropriate for the
-   pointer to member.  The fields are used as follows:
+   where P is either a POINTER_TYPE to a METHOD_TYPE appropriate for
+   the pointer to member, or one plus twice the index into the vtable;
+   the two cases are distinguished by looking at the least significant
+   bit of P.  When FUNCTION_BOUNDARY is less than 16 (and so it might
+   happen that the function pointer might naturally have the low bit
+   set), the type is instead
 
-     If __INDEX is -1, then the function to call is non-virtual, and
-     is located at the address given by __PFN.
-
-     If __INDEX is zero, then this a NULL pointer-to-member.
+   struct {
+     __P __pfn;
+     ptrdiff_t __delta;
+     char __vflag;
+   };
 
-     Otherwise, the function to call is virtual.  Then, __DELTA2 gives
-     the offset from an instance of the object to the virtual function
-     table, and __INDEX - 1 is the index into the vtable to use to
-     find the function.
+   and __pfn is a pointer to a method when __vflag is zero.
 
-     The value to use for the THIS parameter is the address of the
-     object plus __DELTA.
+   In all cases, the value to use for the THIS parameter is the
+   address of the object plus __DELTA / 2 .
 
    For example, given:
 
@@ -2657,27 +2657,9 @@ extern int flag_new_for_scope;
 
    the pointer-to-member for `&S::f' looks like:
 
-     { 4, -1, { &f__2B2 } };
-
-   The `4' means that given an `S*' you have to add 4 bytes to get to
-   the address of the `B2*'.  Then, the -1 indicates that this is a
-   non-virtual function.  Of course, `&f__2B2' is the name of that
-   function.
-
-   (Of course, the exact values may differ depending on the mangling
-   scheme, sizes of types, and such.).
-
-   Under the new ABI, we do:
-
-     struct {
-       __P __pfn;
-       ptrdiff_t __delta;
-     };
+     { &f__2B2, 4, 0 };
 
-   (We don't need DELTA2, because the vtable is always the first thing
-   in the object.)  If the function is virtual, then PFN is one plus
-   twice the index into the vtable; otherwise, it is just a pointer to
-   the function.  */
+*/
 
 /* Get the POINTER_TYPE to the METHOD_TYPE associated with this
    pointer to member function.  TYPE_PTRMEMFUNC_P _must_ be true,
@@ -4469,8 +4451,10 @@ extern int cp_type_quals                        PARAMS ((tree));
 extern int cp_has_mutable_p                     PARAMS ((tree));
 extern int at_least_as_qualified_p              PARAMS ((tree, tree));
 extern int more_qualified_p                     PARAMS ((tree, tree));
-extern tree build_ptrmemfunc1                   PARAMS ((tree, tree, tree));
-extern void expand_ptrmemfunc_cst               PARAMS ((tree, tree *, tree *));
+extern tree build_ptrmemfunc1                   PARAMS ((tree, tree, tree, 
+                                                        tree));
+extern void expand_ptrmemfunc_cst               PARAMS ((tree, tree *, 
+                                                        tree *, tree *));
 extern tree pfn_from_ptrmemfunc                 PARAMS ((tree));
 extern tree type_after_usual_arithmetic_conversions PARAMS ((tree, tree));
 extern tree composite_pointer_type              PARAMS ((tree, tree, tree, tree,
index 54d84f4..b04206d 100644 (file)
@@ -6303,6 +6303,7 @@ initialize_predefined_identifiers ()
     { "nelts", &nelts_identifier, 0 },
     { THIS_NAME, &this_identifier, 0 },
     { VTABLE_PFN_NAME, &pfn_identifier, 0 },
+    { "__vflag", &pfn_vflag_identifier, 0 },
     { "__pfn_or_delta2", &pfn_or_delta2_identifier, 0 },
     { "_vptr", &vptr_identifier, 0 },
     { "__vtt_parm", &vtt_parm_identifier, 0 },
@@ -9156,7 +9157,14 @@ build_ptrmemfunc_type (type)
   fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
   fields[1] = build_decl (FIELD_DECL, delta_identifier,
                          delta_type_node);
-  finish_builtin_type (t, "__ptrmemfunc_type", fields, 1, ptr_type_node);
+  if (FUNCTION_BOUNDARY < 16)
+    {
+      fields[2] = build_decl (FIELD_DECL, pfn_vflag_identifier,
+                             char_type_node);
+      finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node);
+    } else {
+      finish_builtin_type (t, "__ptrmemfunc_type", fields, 1, ptr_type_node);
+    }
 
   /* Zap out the name so that the back-end will give us the debugging
      information for this anonymous RECORD_TYPE.  */
index 6855160..7163a5b 100644 (file)
@@ -62,9 +62,10 @@ cplus_expand_constant (cst)
          {
            tree delta;
            tree pfn;
+           tree flag;
 
-           expand_ptrmemfunc_cst (cst, &delta, &pfn);
-           cst = build_ptrmemfunc1 (type, delta, pfn);
+           expand_ptrmemfunc_cst (cst, &delta, &pfn, &flag);
+           cst = build_ptrmemfunc1 (type, delta, pfn, flag);
          }
       }
       break;
index 440955d..6d010d8 100644 (file)
@@ -2909,9 +2909,22 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
       idx = cp_build_binary_op (TRUNC_DIV_EXPR, 
                                build1 (NOP_EXPR, vtable_index_type, e3),
                                TYPE_SIZE_UNIT (vtable_entry_type));
-      e1 = cp_build_binary_op (BIT_AND_EXPR,
-                              build1 (NOP_EXPR, vtable_index_type, e3),
-                              integer_one_node);
+      if (FUNCTION_BOUNDARY < 16)
+       {
+         tree delta;
+         tree pfn;
+         if (TREE_CODE (function) == PTRMEM_CST)
+           expand_ptrmemfunc_cst (function, &delta, &pfn, &e1);
+         else
+           e1 = build_component_ref (function, pfn_vflag_identifier, 
+                                        NULL_TREE, 0);
+       }
+      else
+       {
+         e1 = cp_build_binary_op (BIT_AND_EXPR,
+                                  build1 (NOP_EXPR, vtable_index_type, e3),
+                                  integer_one_node);
+       }
 
       vtbl = convert_pointer_to (ptr_type_node, instance);
       delta = cp_convert (ptrdiff_type_node,
@@ -5995,23 +6008,34 @@ get_delta_difference (from, to, force)
    the other components as specified.  */
 
 tree
-build_ptrmemfunc1 (type, delta, pfn)
-     tree type, delta, pfn;
+build_ptrmemfunc1 (type, delta, pfn, flag)
+     tree type, delta, pfn, flag;
 {
   tree u = NULL_TREE;
   tree delta_field;
   tree pfn_field;
+  tree vflag_field;
 
   /* Pull the FIELD_DECLs out of the type.  */
   pfn_field = TYPE_FIELDS (type);
   delta_field = TREE_CHAIN (pfn_field);
+  vflag_field = TREE_CHAIN (delta_field);  /* NULL if no such field.  */
 
   /* Make sure DELTA has the type we want.  */
   delta = convert_and_check (delta_type_node, delta);
 
   /* Finish creating the initializer.  */
-  u = tree_cons (pfn_field, pfn,
-                build_tree_list (delta_field, delta));
+  if (FUNCTION_BOUNDARY < 16)
+    {
+      u = tree_cons (pfn_field, pfn,
+                    tree_cons (delta_field, delta,
+                               build_tree_list (vflag_field, flag)));
+    }
+  else
+    {
+      u = tree_cons (pfn_field, pfn,
+                    build_tree_list (delta_field, delta));
+    }
   u = build (CONSTRUCTOR, type, NULL_TREE, u);
   TREE_CONSTANT (u) = TREE_CONSTANT (pfn) && TREE_CONSTANT (delta);
   TREE_STATIC (u) = (TREE_CONSTANT (u)
@@ -6047,6 +6071,7 @@ build_ptrmemfunc (type, pfn, force)
     {
       tree delta = NULL_TREE;
       tree npfn = NULL_TREE;
+      tree flag = NULL_TREE;
       tree n;
 
       if (!force 
@@ -6075,18 +6100,21 @@ build_ptrmemfunc (type, pfn, force)
 
       /* Obtain the function pointer and the current DELTA.  */
       if (TREE_CODE (pfn) == PTRMEM_CST)
-       expand_ptrmemfunc_cst (pfn, &delta, &npfn);
+       expand_ptrmemfunc_cst (pfn, &delta, &npfn, &flag);
       else
        {
          npfn = build_component_ref (pfn, pfn_identifier, NULL_TREE, 0);
          delta = build_component_ref (pfn, delta_identifier, NULL_TREE, 0);
+         if (FUNCTION_BOUNDARY < 16)
+           flag = build_component_ref (pfn, pfn_vflag_identifier, 
+                                       NULL_TREE, 0);
        }
 
       /* Under the new ABI, the conversion is easy.  Just adjust
         the DELTA field.  */
       delta = cp_convert (ptrdiff_type_node, delta);
       delta = cp_build_binary_op (PLUS_EXPR, delta, n);
-      return build_ptrmemfunc1 (to_type, delta, npfn);
+      return build_ptrmemfunc1 (to_type, delta, npfn, flag);
     }
 
   /* Handle null pointer to member function conversions.  */
@@ -6095,7 +6123,8 @@ build_ptrmemfunc (type, pfn, force)
       pfn = build_c_cast (type, integer_zero_node);
       return build_ptrmemfunc1 (to_type,
                                integer_zero_node, 
-                               pfn);
+                               pfn,
+                               integer_zero_node);
     }
 
   if (type_unknown_p (pfn))
@@ -6106,7 +6135,7 @@ build_ptrmemfunc (type, pfn, force)
   return make_ptrmem_cst (to_type, fn);
 }
 
-/* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST
+/* Return the DELTA, PFN, and FLAG values for the PTRMEM_CST
    given by CST.
 
    ??? There is no consistency as to the types returned for the above
@@ -6114,10 +6143,11 @@ build_ptrmemfunc (type, pfn, force)
    integer_type_node.  */
 
 void
-expand_ptrmemfunc_cst (cst, delta, pfn)
+expand_ptrmemfunc_cst (cst, delta, pfn, flag)
      tree cst;
      tree *delta;
      tree *pfn;
+     tree *flag;
 {
   tree type = TREE_TYPE (cst);
   tree fn = PTRMEM_CST_MEMBER (cst);
@@ -6135,7 +6165,10 @@ expand_ptrmemfunc_cst (cst, delta, pfn)
   *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0);
 
   if (!DECL_VIRTUAL_P (fn))
-    *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn));
+    {
+      *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn));
+      *flag = integer_zero_node;
+    }
   else
     {
       /* If we're dealing with a virtual function, we have to adjust 'this'
@@ -6155,6 +6188,7 @@ expand_ptrmemfunc_cst (cst, delta, pfn)
                          integer_one_node));
       *pfn = fold (build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type),
                           *pfn));
+      *flag = integer_one_node;
     }
 }
 
@@ -6169,8 +6203,9 @@ pfn_from_ptrmemfunc (t)
     {
       tree delta;
       tree pfn;
+      tree flag;
       
-      expand_ptrmemfunc_cst (t, &delta, &pfn);
+      expand_ptrmemfunc_cst (t, &delta, &pfn, &flag);
       if (pfn)
        return pfn;
     }