OSDN Git Service

(struct function): Make frame_offset be HOST_WIDE_INT.
[pf3gnuchains/gcc-fork.git] / gcc / cp / sig.c
index b50eee4..7e53de6 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions dealing with signatures and signature pointers/references.
-   Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
    Contributed by Gerald Baumgartner (gb@cs.purdue.edu)
 
 This file is part of GNU CC.
@@ -153,8 +153,7 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
         const s * sptr;
        };
 
-     Similarly, for `volatile' and `const volatile'.
-   */
+     Similarly, for `volatile' and `const volatile'.  */
 
   t = make_lang_type (RECORD_TYPE);
   {
@@ -185,7 +184,10 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
 
     TREE_CHAIN (optr) = sptr;
     TYPE_FIELDS (t) = optr;
-    TYPE_ALIGN (t) = TYPE_ALIGN (optr_type);
+    /* Allow signature pointers/references to be grabbed 2 words at a time.
+       For this to work on a Sparc, we need 8-byte alignment.  */
+    TYPE_ALIGN (t) = MAX (TYPE_ALIGN (double_type_node),
+                         TYPE_ALIGN (optr_type));
 
     /* A signature pointer/reference type isn't a `real' class type.  */
     IS_AGGR_TYPE (t) = 0;
@@ -420,6 +422,7 @@ match_method_types (sig_mtype, class_mtype)
 }
 
 /* Undo casts of opaque type variables to the RHS types.  */
+
 static void
 undo_casts (sig_ty)
      tree sig_ty;
@@ -530,11 +533,11 @@ build_signature_table_constructor (sig_ty, rhs)
 
          if (rhs_method == NULL_TREE
              || (compute_access (basetypes, rhs_method)
-                 != access_public))
+                 != access_public_node))
            {
              error ("class `%s' does not contain a method conforming to `%s'",
                     TYPE_NAME_STRING (rhstype),
-                    fndecl_as_string (NULL, sig_method, 1));
+                    fndecl_as_string (sig_method, 1));
              undo_casts (sig_ty);
              return error_mark_node;
            }
@@ -559,7 +562,7 @@ build_signature_table_constructor (sig_ty, rhs)
        }
       else
        {
-         tree tag, vb_off, delta, index, pfn, vt_off;
+         tree tag, vb_off, delta, idx, pfn, vt_off;
          tree tag_decl, vb_off_decl, delta_decl, index_decl;
          tree pfn_decl, vt_off_decl;
 
@@ -569,8 +572,9 @@ build_signature_table_constructor (sig_ty, rhs)
              tag = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
              vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
              delta = integer_zero_node;
-             index = integer_zero_node;
-             pfn = build_unary_op (ADDR_EXPR, rhs_method, 0);
+             idx = integer_zero_node;
+             pfn = build_addr_func (rhs_method);
+             TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (rhs_method)) = 1;
              TREE_TYPE (pfn) = ptr_type_node;
              TREE_ADDRESSABLE (rhs_method) = 1;
              offset_p = 0;     /* we can't offset the rhs sig table */
@@ -580,9 +584,13 @@ build_signature_table_constructor (sig_ty, rhs)
              /* virtual member function */
              tag = integer_one_node;
              vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
-             delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method),
-                                              rhstype, 1));
-             index = DECL_VINDEX (rhs_method);
+             if (flag_vtable_thunks)
+               delta = BINFO_OFFSET
+                 (get_binfo (DECL_CONTEXT (rhs_method), rhstype, 1));
+             else
+               delta = BINFO_OFFSET
+                 (get_binfo (DECL_CLASS_CONTEXT (rhs_method), rhstype, 1));
+             idx = DECL_VINDEX (rhs_method);
              vt_off = get_vfield_offset (get_binfo (DECL_CONTEXT (rhs_method),
                                                     rhstype, 0));
            }
@@ -593,8 +601,9 @@ build_signature_table_constructor (sig_ty, rhs)
              vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
              delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method),
                                               rhstype, 1));
-             index = integer_zero_node;
-             pfn = build_unary_op (ADDR_EXPR, rhs_method, 0);
+             idx = integer_zero_node;
+             pfn = build_addr_func (rhs_method);
+             TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (rhs_method)) = 1;
              TREE_TYPE (pfn) = ptr_type_node;
              TREE_ADDRESSABLE (rhs_method) = 1;
            }
@@ -612,7 +621,7 @@ build_signature_table_constructor (sig_ty, rhs)
          tag = convert (TREE_TYPE (tag_decl), tag);
          vb_off = convert (TREE_TYPE (vb_off_decl), vb_off);
          delta = convert (TREE_TYPE (delta_decl), delta);
-         index = convert (TREE_TYPE (index_decl), index);
+         idx = convert (TREE_TYPE (index_decl), idx);
 
          if (DECL_VINDEX (rhs_method))
            {
@@ -627,7 +636,7 @@ build_signature_table_constructor (sig_ty, rhs)
              tbl_entry = build_tree_list (pfn_decl, pfn);
            }
          tbl_entry = tree_cons (delta_decl, delta,
-                                tree_cons (index_decl, index, tbl_entry));
+                                tree_cons (index_decl, idx, tbl_entry));
          tbl_entry = tree_cons (tag_decl, tag,
                                 tree_cons (vb_off_decl, vb_off, tbl_entry));
          tbl_entry = build (CONSTRUCTOR, sigtable_entry_type,
@@ -910,22 +919,24 @@ save_this (instance)
 /* Build a signature member function call.  Looks up the signature table
    entry corresponding to FUNCTION.  Depending on the value of the CODE
    field, either call the function in PFN directly, or use OFFSET to
-   index INSTANCE's virtual function table.  */
+   index the object's virtual function table.  */
 
 tree
-build_signature_method_call (basetype, instance, function, parms)
-     tree basetype, instance, function, parms;
+build_signature_method_call (function, parms)
+     tree function, parms;
 {
+  tree instance = TREE_VALUE (parms);
   tree saved_instance = save_this (instance);  /* Create temp for `this'.  */
   tree object_ptr = build_optr_ref (saved_instance);
   tree new_object_ptr, new_parms;
   tree signature_tbl_ptr = build_sptr_ref (saved_instance);
   tree sig_field_name = DECL_NAME (DECL_MEMFUNC_POINTER_TO (function));
+  tree basetype = DECL_CONTEXT (function);
   tree basetype_path = TYPE_BINFO (basetype);
   tree tbl_entry = build_component_ref (build1 (INDIRECT_REF, basetype,
                                                signature_tbl_ptr),
                                        sig_field_name, basetype_path, 1);
-  tree tag, delta, pfn, vt_off, index, vfn;
+  tree tag, delta, pfn, vt_off, idx, vfn;
   tree deflt_call = NULL_TREE, direct_call, virtual_call, result;
 
   tbl_entry = save_expr (tbl_entry);
@@ -933,7 +944,7 @@ build_signature_method_call (basetype, instance, function, parms)
   delta = build_component_ref (tbl_entry, delta_identifier, NULL_TREE, 1);
   pfn = build_component_ref (tbl_entry, pfn_identifier, NULL_TREE, 1);
   vt_off = build_component_ref (tbl_entry, vt_off_identifier, NULL_TREE, 1);
-  index = build_component_ref (tbl_entry, index_identifier, NULL_TREE, 1);
+  idx = build_component_ref (tbl_entry, index_identifier, NULL_TREE, 1);
   TREE_TYPE (pfn) = build_pointer_type (TREE_TYPE (function)); 
 
   if (IS_DEFAULT_IMPLEMENTATION (function))
@@ -942,12 +953,12 @@ build_signature_method_call (basetype, instance, function, parms)
       deflt_call = build_function_call (pfn, parms);
     }
 
-  new_object_ptr = build (PLUS_EXPR, TYPE_POINTER_TO (basetype),
+  new_object_ptr = build (PLUS_EXPR, build_pointer_type (basetype),
                          convert (ptrdiff_type_node, object_ptr),
                          convert (ptrdiff_type_node, delta));
 
   parms = tree_cons (NULL_TREE,
-                    convert (TYPE_POINTER_TO (basetype), object_ptr),
+                    convert (build_pointer_type (basetype), object_ptr),
                     TREE_CHAIN (parms));
   new_parms = tree_cons (NULL_TREE, new_object_ptr, TREE_CHAIN (parms));
 
@@ -956,7 +967,7 @@ build_signature_method_call (basetype, instance, function, parms)
     tree old_this = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn))));
 
     TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))) =
-      build_type_variant (TYPE_POINTER_TO (basetype),
+      build_type_variant (build_pointer_type (basetype),
                          TYPE_READONLY (old_this),
                          TYPE_VOLATILE (old_this));
 
@@ -971,19 +982,16 @@ build_signature_method_call (basetype, instance, function, parms)
                    convert (ptrdiff_type_node, vt_off));
       vtbl = build_indirect_ref (build_indirect_ref (vfld, NULL_PTR),
                                 NULL_PTR);
-      aref = build_array_ref (vtbl, index);
+      aref = build_array_ref (vtbl, idx);
 
       if (flag_vtable_thunks)
        vfn = aref;
       else
-       vfn = build_component_ref (aref, pfn_identifier, 0, 0);
+       vfn = build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
 
       TREE_TYPE (vfn) = build_pointer_type (TREE_TYPE (function));
 
-      if (flag_vtable_thunks)
-       virtual_call = build_function_call (vfn, parms);
-      else
-       virtual_call = build_function_call (vfn, new_parms);
+      virtual_call = build_function_call (vfn, new_parms);
     }
 
     /* Undo the cast, make `this' a signature pointer again.  */
@@ -998,7 +1006,7 @@ build_signature_method_call (basetype, instance, function, parms)
          && (!deflt_call || deflt_call == error_mark_node)))
     {
       compiler_error ("cannot build call of signature member function `%s'",
-                     fndecl_as_string (NULL, function, 1));
+                     fndecl_as_string (function, 1));
       return error_mark_node;
     }