cp-tree.h (DELTA_FROM_VTABLE_ENTRY): Remove.
authorMark Mitchell <mark@codesourcery.com>
Fri, 5 May 2000 03:10:42 +0000 (03:10 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Fri, 5 May 2000 03:10:42 +0000 (03:10 +0000)
* cp-tree.h (DELTA_FROM_VTABLE_ENTRY): Remove.
(SET_FNADDR_FROM_VTABLE_ENTRY): Likewise.
(lang_decl_flags): Add vcall_offset.
(THUNK_VCALL_OFFSET): Use it.
* decl.c (lang_mark_tree): Don't mark DECL_ACCESS for a thunk.
* method.c (make_thunk): Create the lang_decl here, not in
emit_thunk.
(emit_thunk): Make generic thunks into ordinary functions once
they have been fed to expand_body.
* semantics.c (expand_body): Set current_function_is_thunk here.

From-SVN: r33699

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/method.c
gcc/cp/semantics.c

index 42f2338..636f30e 100644 (file)
@@ -1,3 +1,16 @@
+2000-05-04  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (DELTA_FROM_VTABLE_ENTRY): Remove.
+       (SET_FNADDR_FROM_VTABLE_ENTRY): Likewise.
+       (lang_decl_flags): Add vcall_offset.
+       (THUNK_VCALL_OFFSET): Use it.
+       * decl.c (lang_mark_tree): Don't mark DECL_ACCESS for a thunk.
+       * method.c (make_thunk): Create the lang_decl here, not in
+       emit_thunk.
+       (emit_thunk): Make generic thunks into ordinary functions once
+       they have been fed to expand_body.
+       * semantics.c (expand_body): Set current_function_is_thunk here.
+
 2000-05-04  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * class.c (update_vtable_entry_for_fn): Prototype.
index 5e2b433..cb46967 100644 (file)
@@ -1294,13 +1294,6 @@ enum languages { lang_c, lang_cplusplus, lang_java };
   ((CP_TYPE_QUALS (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))     \
    == TYPE_QUAL_CONST)
 
-#define DELTA_FROM_VTABLE_ENTRY(ENTRY)                         \
-  (!flag_vtable_thunks ?                                       \
-     TREE_VALUE (CONSTRUCTOR_ELTS (ENTRY))                     \
-   : !DECL_THUNK_P (TREE_OPERAND ((ENTRY), 0))                         \
-   ? integer_zero_node                                         \
-   : build_int_2 (THUNK_DELTA (TREE_OPERAND ((ENTRY), 0)), 0))
-
 /* Virtual function addresses can be gotten from a virtual function
    table entry using this macro.  */
 #define FNADDR_FROM_VTABLE_ENTRY(ENTRY)                                        \
@@ -1310,8 +1303,6 @@ enum languages { lang_c, lang_cplusplus, lang_java };
    ? (ENTRY)                                                           \
    : DECL_INITIAL (TREE_OPERAND ((ENTRY), 0)))
 
-#define SET_FNADDR_FROM_VTABLE_ENTRY(ENTRY,VALUE) \
-  (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (ENTRY)))) = (VALUE))
 #define FUNCTION_ARG_CHAIN(NODE) (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))))
 #define PROMOTES_TO_AGGR_TYPE(NODE,CODE)       \
   (((CODE) == TREE_CODE (NODE)                 \
@@ -1900,6 +1891,10 @@ struct lang_decl_flags
     /* In a namespace-scope FUNCTION_DECL, this is
        GLOBAL_INIT_PRIORITY.  */
     int init_priority;
+
+    /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
+       THUNK_VCALL_OFFSET.  */
+    HOST_WIDE_INT vcall_offset;
   } u2;
 };
 
@@ -3039,7 +3034,8 @@ extern int flag_new_for_scope;
    vtable for the `this' pointer to find the vcall offset.  (The vptr
    is always located at offset zero from the f `this' pointer.)  If
    zero, then there is no vcall offset.  */
-#define THUNK_VCALL_OFFSET(DECL) (DECL_CHECK (DECL)->decl.u2.i)
+#define THUNK_VCALL_OFFSET(DECL) \
+  (DECL_LANG_SPECIFIC (DECL)->decl_flags.u2.vcall_offset)
 
 /* DECL_NEEDED_P holds of a declaration when we need to emit its
    definition.  This is true when the back-end tells us that
index c792e74..81203b4 100644 (file)
@@ -14731,7 +14731,9 @@ lang_mark_tree (t)
       if (ld)
        {
          ggc_mark (ld);
-         if (!DECL_GLOBAL_CTOR_P (t) && !DECL_GLOBAL_DTOR_P (t))
+         if (!DECL_GLOBAL_CTOR_P (t) 
+             && !DECL_GLOBAL_DTOR_P (t)
+             && !DECL_THUNK_P (t))
            ggc_mark_tree (ld->decl_flags.u2.access);
          ggc_mark_tree (ld->decl_flags.context);
          if (TREE_CODE (t) != NAMESPACE_DECL)
index 07173d7..6491e2b 100644 (file)
@@ -2055,6 +2055,9 @@ make_thunk (function, delta, vcall_index)
   if (thunk == NULL_TREE)
     {
       thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl));
+      DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (func_decl);
+      copy_lang_decl (func_decl);
+      DECL_CONTEXT (thunk) = DECL_CONTEXT (func_decl);
       TREE_READONLY (thunk) = TREE_READONLY (func_decl);
       TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (func_decl);
       comdat_linkage (thunk);
@@ -2063,12 +2066,22 @@ make_thunk (function, delta, vcall_index)
       THUNK_DELTA (thunk) = delta;
       THUNK_VCALL_OFFSET (thunk) 
        = vcall_index * int_size_in_bytes (vtable_entry_type);
+      /* The thunk itself is not a constructor or destructor, even if
+       the thing it is thunking to is.  */
+      DECL_INTERFACE_KNOWN (thunk) = 1;
+      DECL_NOT_REALLY_EXTERN (thunk) = 1;
+      DECL_SAVED_FUNCTION_DATA (thunk) = NULL;
+      DECL_DESTRUCTOR_P (thunk) = 0;
+      DECL_CONSTRUCTOR_P (thunk) = 0;
       DECL_EXTERNAL (thunk) = 1;
       DECL_ARTIFICIAL (thunk) = 1;
-      DECL_CONTEXT (thunk) = DECL_CONTEXT (func_decl);
       /* Even if this thunk is a member of a local class, we don't
         need a static chain.  */
       DECL_NO_STATIC_CHAIN (thunk) = 1;
+      /* The THUNK is not a pending inline, even if the FUNC_DECL is.  */
+      DECL_PENDING_INLINE_P (thunk) = 0;
+      /* Nor has it been deferred.  */
+      DECL_DEFERRED_FN (thunk) = 0;
       /* So that finish_file can write out any thunks that need to be: */
       pushdecl_top_level (thunk);
     }
@@ -2081,15 +2094,25 @@ void
 emit_thunk (thunk_fndecl)
      tree thunk_fndecl;
 {
-  tree fnaddr = DECL_INITIAL (thunk_fndecl);
-  tree function = TREE_OPERAND (fnaddr, 0);
-  int delta = THUNK_DELTA (thunk_fndecl);
-  int vcall_offset = THUNK_VCALL_OFFSET (thunk_fndecl);
+  tree fnaddr;
+  tree function;
+  int delta;
+  int vcall_offset;
 
   if (TREE_ASM_WRITTEN (thunk_fndecl))
     return;
 
-  TREE_ASM_WRITTEN (thunk_fndecl) = 1;
+  if (TREE_CODE (DECL_INITIAL (thunk_fndecl)) != ADDR_EXPR)
+    /* We already turned this thunk into an ordinary function.
+       There's no need to process this thunk again.  (We can't just
+       clear DECL_THUNK_P because that will confuse
+       FNADDR_FROM_VTABLE_ENTRY and friends.)  */
+    return;
+
+  fnaddr = DECL_INITIAL (thunk_fndecl);
+  function = TREE_OPERAND (fnaddr, 0);
+  delta = THUNK_DELTA (thunk_fndecl);
+  vcall_offset = THUNK_VCALL_OFFSET (thunk_fndecl);
 
   TREE_ADDRESSABLE (function) = 1;
   mark_used (function);
@@ -2097,8 +2120,14 @@ emit_thunk (thunk_fndecl)
   if (current_function_decl)
     abort ();
 
+  if (flag_syntax_only)
+    {
+      TREE_ASM_WRITTEN (thunk_fndecl) = 1;
+      return;
+    }
+
 #ifdef ASM_OUTPUT_MI_THUNK
-  if (!flag_syntax_only && vcall_offset == 0)
+  if (vcall_offset == 0)
     {
       const char *fnname;
       current_function_decl = thunk_fndecl;
@@ -2115,6 +2144,7 @@ emit_thunk (thunk_fndecl)
       assemble_end_function (thunk_fndecl, fnname);
       current_function_decl = 0;
       cfun = 0;
+      TREE_ASM_WRITTEN (thunk_fndecl) = 1;
     }
   else
 #endif /* ASM_OUTPUT_MI_THUNK */
@@ -2141,21 +2171,10 @@ emit_thunk (thunk_fndecl)
     a = nreverse (t);
     DECL_ARGUMENTS (thunk_fndecl) = a;
     DECL_RESULT (thunk_fndecl) = NULL_TREE;
-    DECL_LANG_SPECIFIC (thunk_fndecl) = DECL_LANG_SPECIFIC (function);
-    copy_lang_decl (thunk_fndecl);
-    DECL_INTERFACE_KNOWN (thunk_fndecl) = 1;
-    DECL_NOT_REALLY_EXTERN (thunk_fndecl) = 1;
-    DECL_SAVED_FUNCTION_DATA (thunk_fndecl) = NULL;
-
-    /* The thunk itself is not a constructor or destructor, even if
-       the thing it is thunking to is.  */
-    DECL_DESTRUCTOR_P (thunk_fndecl) = 0;
-    DECL_CONSTRUCTOR_P (thunk_fndecl) = 0;
 
     push_to_top_level ();
     start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
     store_parm_decls ();
-    current_function_is_thunk = 1;
 
     /* Adjust the this pointer by the constant.  */
     t = ssize_int (delta);
@@ -2199,19 +2218,12 @@ emit_thunk (thunk_fndecl)
       finish_expr_stmt (t);
 
     /* The back-end expects DECL_INITIAL to contain a BLOCK, so we
-       clear this here.  */
-    DECL_INITIAL (thunk_fndecl) = NULL_TREE;
+       create one.  */
     DECL_INITIAL (thunk_fndecl) = make_node (BLOCK);
     BLOCK_VARS (DECL_INITIAL (thunk_fndecl)) 
       = DECL_ARGUMENTS (thunk_fndecl);
     expand_body (finish_function (0));
-    /* Restore the DECL_INITIAL for the THUNK_DECL.  */
-    DECL_INITIAL (thunk_fndecl) = fnaddr;
     pop_from_top_level ();
-
-    /* Don't let the backend defer this function.  */
-    if (DECL_DEFER_OUTPUT (thunk_fndecl))
-      output_inline_function (thunk_fndecl);
   }
 }
 \f
index 8b9bfac..d6d493f 100644 (file)
@@ -2775,6 +2775,7 @@ expand_body (fn)
 
   start_function (NULL_TREE, fn, NULL_TREE, SF_PRE_PARSED | SF_EXPAND);
   store_parm_decls ();
+  current_function_is_thunk = DECL_THUNK_P (fn);
 
   /* We don't need to redeclare __FUNCTION__, __PRETTY_FUNCTION__, or
      any of the other magic variables we set up when starting a