class.c (build_vtbl_ref_1): Use fixed_type_or_null.
authorJason Merrill <jason@redhat.com>
Mon, 13 May 2002 08:00:48 +0000 (04:00 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 13 May 2002 08:00:48 +0000 (04:00 -0400)
        * class.c (build_vtbl_ref_1): Use fixed_type_or_null.
        (fixed_type_or_null): See through reference vars.
        (build_base_path): Vtable contents are constant.
        * typeck.c (get_member_function_from_ptrfunc): Likewise.

        * rtti.c (emit_tinfo_decl): Call import_export_decl.
        * decl2.c (import_export_decl): Set DECL_NOT_REALLY_EXTERN on
        tinfo decls by default.  Don't mess with the builtins.

From-SVN: r53416

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl2.c
gcc/cp/rtti.c
gcc/cp/typeck.c

index b1eda6126ab7a4c2b3cefe4166103ce5f073687a..da89625e155e7a24304885614e7d7f5273c03189 100644 (file)
@@ -1,3 +1,14 @@
+2002-05-13  Jason Merrill  <jason@redhat.com>
+
+       * class.c (build_vtbl_ref_1): Use fixed_type_or_null.
+       (fixed_type_or_null): See through reference vars.
+       (build_base_path): Vtable contents are constant.
+       * typeck.c (get_member_function_from_ptrfunc): Likewise.
+
+       * rtti.c (emit_tinfo_decl): Call import_export_decl.
+       * decl2.c (import_export_decl): Set DECL_NOT_REALLY_EXTERN on
+       tinfo decls by default.  Don't mess with the builtins.
+
 2002-05-12  Jason Merrill  <jason@redhat.com>
 
        * cp-lang.c (ok_to_generate_alias_set_for_type): Backend-created
index b06828f12033ce9734bd4d5253d8ec46ab04d30d..98f32dccb14b6dadfd19597476e0d79f4b2f67af 100644 (file)
@@ -316,7 +316,8 @@ build_base_path (code, expr, binfo, nonnull)
                         build_pointer_type (ptrdiff_type_node),
                         v_offset);
       v_offset = build_indirect_ref (v_offset, NULL);
-      
+      TREE_CONSTANT (v_offset) = 1;
+
       offset = cp_convert (ptrdiff_type_node,
                           size_diffop (offset, BINFO_OFFSET (v_binfo)));
 
@@ -401,75 +402,36 @@ static tree
 build_vtbl_ref_1 (instance, idx)
      tree instance, idx;
 {
-  tree vtbl, aref;
-  tree basetype = TREE_TYPE (instance);
+  tree aref;
+  tree vtbl = NULL_TREE;
+
+  /* Try to figure out what a reference refers to, and
+     access its virtual function table directly.  */
+
+  int cdtorp = 0;
+  tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
 
+  tree basetype = TREE_TYPE (instance);
   if (TREE_CODE (basetype) == REFERENCE_TYPE)
     basetype = TREE_TYPE (basetype);
 
-  if (instance == current_class_ref)
-    vtbl = build_vfield_ref (instance, basetype);
-  else
+  if (fixed_type && !cdtorp)
     {
-      if (optimize)
-       {
-         /* Try to figure out what a reference refers to, and
-            access its virtual function table directly.  */
-         tree ref = NULL_TREE;
-
-         if (TREE_CODE (instance) == INDIRECT_REF
-             && TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE)
-           ref = TREE_OPERAND (instance, 0);
-         else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
-           ref = instance;
-
-         if (ref && TREE_CODE (ref) == VAR_DECL
-             && DECL_INITIAL (ref))
-           {
-             tree init = DECL_INITIAL (ref);
-
-             while (TREE_CODE (init) == NOP_EXPR
-                    || TREE_CODE (init) == NON_LVALUE_EXPR)
-               init = TREE_OPERAND (init, 0);
-             if (TREE_CODE (init) == ADDR_EXPR)
-               {
-                 init = TREE_OPERAND (init, 0);
-                 if (IS_AGGR_TYPE (TREE_TYPE (init))
-                     && (TREE_CODE (init) == PARM_DECL
-                         || TREE_CODE (init) == VAR_DECL))
-                   instance = init;
-               }
-           }
-       }
+      tree binfo = lookup_base (fixed_type, basetype,
+                               ba_ignore|ba_quiet, NULL);
+      if (binfo)
+       vtbl = BINFO_VTABLE (binfo);
+    }
 
-      if (IS_AGGR_TYPE (TREE_TYPE (instance))
-         && (TREE_CODE (instance) == RESULT_DECL
-             || TREE_CODE (instance) == PARM_DECL
-             || TREE_CODE (instance) == VAR_DECL))
-       {
-         vtbl = TYPE_BINFO_VTABLE (basetype);
-         /* Knowing the dynamic type of INSTANCE we can easily obtain
-            the correct vtable entry.  We resolve this back to be in
-            terms of the primary vtable.  */
-         if (TREE_CODE (vtbl) == PLUS_EXPR)
-           {
-             idx = fold (build (PLUS_EXPR,
-                                TREE_TYPE (idx),
-                                idx,
-                                build (EXACT_DIV_EXPR,
-                                       TREE_TYPE (idx),
-                                       TREE_OPERAND (vtbl, 1),
-                                       TYPE_SIZE_UNIT (vtable_entry_type))));
-             vtbl = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
-           }
-       }
-      else
-       vtbl = build_vfield_ref (instance, basetype);
+  if (!vtbl)
+    {
+      vtbl = build_vfield_ref (instance, basetype);
     }
 
   assemble_external (vtbl);
 
   aref = build_array_ref (vtbl, idx);
+  TREE_CONSTANT (aref) = 1;
 
   return aref;
 }
@@ -5396,7 +5358,7 @@ fixed_type_or_null (instance, nonnull, cdtorp)
        return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
       if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
        /* Propagate nonnull.  */
-       fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+       return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
       return NULL_TREE;
 
     case NOP_EXPR:
@@ -5423,6 +5385,7 @@ fixed_type_or_null (instance, nonnull, cdtorp)
       /* fall through...  */
     case TARGET_EXPR:
     case PARM_DECL:
+    case RESULT_DECL:
       if (IS_AGGR_TYPE (TREE_TYPE (instance)))
        {
          if (nonnull)
@@ -5449,6 +5412,11 @@ fixed_type_or_null (instance, nonnull, cdtorp)
           /* Reference variables should be references to objects.  */
           if (nonnull)
            *nonnull = 1;
+
+         if (TREE_CODE (instance) == VAR_DECL
+             && DECL_INITIAL (instance))
+           return fixed_type_or_null (DECL_INITIAL (instance),
+                                      nonnull, cdtorp);
        }
       return NULL_TREE;
 
index 2054a37e545208b5264f54d7336994ca50fdc40f..2fd67ae8740ab380077773b3ce0d54b92f66fcbe 100644 (file)
@@ -2514,6 +2514,7 @@ import_export_decl (decl)
       if (IS_AGGR_TYPE (ctype))
        import_export_class (ctype);
 
+      DECL_NOT_REALLY_EXTERN (decl) = 1;
       if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype)
          && TYPE_POLYMORPHIC_P (ctype)
          /* If -fno-rtti, we're not necessarily emitting this stuff with
@@ -2537,9 +2538,9 @@ import_export_decl (decl)
          if (flag_weak)
            comdat_linkage (decl);
        }
-      else if (TYPE_BUILT_IN (ctype) 
-              && same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
-       DECL_NOT_REALLY_EXTERN (decl) = 0;
+      /* We used to exclude the builtin types here, but that broke
+        emit_support_tinfos.  Let rtti.c choose whether or not to emit
+        them.  */
       else
        comdat_linkage (decl);
     } 
index 16df801b0d0390727c1fa6fb57d8f6abef4d2213..63ffcb7bef0f00b2bed1b4c6a30a140d0393ee32 100644 (file)
@@ -1462,9 +1462,11 @@ emit_tinfo_decl (decl_ptr, data)
   my_friendly_assert (TREE_TYPE (tinfo_decl) == tinfo_decl_type, 20000121);
   tinfo_type = TREE_TYPE (DECL_NAME (tinfo_decl));
   my_friendly_assert (tinfo_type != NULL_TREE, 20000120);
-  
-  if (!DECL_NEEDED_P (tinfo_decl))
+
+  import_export_decl (tinfo_decl);
+  if (DECL_REALLY_EXTERN (tinfo_decl) || !DECL_NEEDED_P (tinfo_decl))
     return 0;
+
   /* Say we've dealt with it.  */
   TREE_TYPE (DECL_NAME (tinfo_decl)) = NULL_TREE;
   
index 329bc3300ca1a3fd3e1d1c43228924a4f9d4ce2a..3b92a64ac830219b898226c9fef7b4e5dd60777d 100644 (file)
@@ -2911,6 +2911,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
       /* Finally, extract the function pointer from the vtable.  */
       e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx));
       e2 = build_indirect_ref (e2, NULL);
+      TREE_CONSTANT (e2) = 1;
 
       /* When using function descriptors, the address of the
         vtable entry is treated as a function pointer.  */