diff options
| author | Mark Mitchell <mark@codesourcery.com> | 2002-10-25 19:39:47 +0000 | 
|---|---|---|
| committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2002-10-25 19:39:47 +0000 | 
| commit | bb5e8a7ffc01267f79f7d3a70b98a29fc6eb604c (patch) | |
| tree | bc8ca7b32029d71b1854594ff6c94c1ba702f188 /gcc/cp/method.c | |
| parent | f3763a442e854320fd233fd63b7871f301f723be (diff) | |
| download | gcc-bb5e8a7ffc01267f79f7d3a70b98a29fc6eb604c.zip gcc-bb5e8a7ffc01267f79f7d3a70b98a29fc6eb604c.tar.gz gcc-bb5e8a7ffc01267f79f7d3a70b98a29fc6eb604c.tar.bz2 | |
class.c (build_vtbl_initializer): Don't use build_vtable_entry.
	* class.c (build_vtbl_initializer): Don't use build_vtable_entry.
	(build_vtable_entry): Remove.
	* cp-tree.h (BINFO_VIRTUALS): Expand documentation.
	(lang_decl): Add thunks.
	(DECL_THUNKS): New macro.
	* decl.c (duplicate_decls): Copy it.
	* method.c (make_thunk): Simplify, and add thunks to DECL_THUNKS.
	* semantics.c (emit_associated_thunks): Simplify.
	* g++.dg/abi/vthunk2.C: New test.
From-SVN: r58536
Diffstat (limited to 'gcc/cp/method.c')
| -rw-r--r-- | gcc/cp/method.c | 107 | 
1 files changed, 54 insertions, 53 deletions
| diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 60a0dce..8a905b2 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -278,10 +278,11 @@ make_thunk (function, delta, vcall_index)  {    tree thunk_id;    tree thunk; -  tree func_decl;    tree vcall_offset;    HOST_WIDE_INT d; +  my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 20021025); +    /* Scale the VCALL_INDEX to be in terms of bytes.  */    if (vcall_index)      vcall_offset  @@ -294,59 +295,59 @@ make_thunk (function, delta, vcall_index)    d = tree_low_cst (delta, 0); -  if (TREE_CODE (function) != ADDR_EXPR) -    abort (); -  func_decl = TREE_OPERAND (function, 0); -  if (TREE_CODE (func_decl) != FUNCTION_DECL) -    abort (); +  /* See if we already have the thunk in question.  */ +  for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk)) +    if (THUNK_DELTA (thunk) == d +	&& ((THUNK_VCALL_OFFSET (thunk) != NULL_TREE) +	    == (vcall_offset != NULL_TREE)) +	&& (THUNK_VCALL_OFFSET (thunk) +	    ? tree_int_cst_equal (THUNK_VCALL_OFFSET (thunk),  +				  vcall_offset) +	    : true)) +      return thunk; + +  /* All thunks must be created before FUNCTION is actually emitted; +     the ABI requires that all thunks be emitted together with the +     function to which they transfer control.  */ +  my_friendly_assert (!TREE_ASM_WRITTEN (function), 20021025); + +  thunk_id = mangle_thunk (function, delta, vcall_offset); +  thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (function)); +  DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function); +  cxx_dup_lang_specific_decl (function); +  SET_DECL_ASSEMBLER_NAME (thunk, thunk_id); +  DECL_CONTEXT (thunk) = DECL_CONTEXT (function); +  TREE_READONLY (thunk) = TREE_READONLY (function); +  TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function); +  TREE_PUBLIC (thunk) = TREE_PUBLIC (function); +  if (flag_weak) +    comdat_linkage (thunk); +  SET_DECL_THUNK_P (thunk); +  DECL_INITIAL (thunk) = build1 (ADDR_EXPR, vfunc_ptr_type_node, function); +  THUNK_DELTA (thunk) = d; +  THUNK_VCALL_OFFSET (thunk) = vcall_offset; +  /* 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; +  /* And neither is it a clone.  */ +  DECL_CLONED_FUNCTION (thunk) = NULL_TREE; +  DECL_EXTERNAL (thunk) = 1; +  DECL_ARTIFICIAL (thunk) = 1; +  /* 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 FUNCTION is.  */ +  DECL_PENDING_INLINE_P (thunk) = 0; +  /* Nor has it been deferred.  */ +  DECL_DEFERRED_FN (thunk) = 0; +  /* Add it to the list of thunks associated with FUNCTION.  */ +  TREE_CHAIN (thunk) = DECL_THUNKS (function); +  DECL_THUNKS (function) = thunk; -  thunk_id = mangle_thunk (TREE_OPERAND (function, 0),  -			   delta, vcall_offset); -  thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id); -  if (thunk && !DECL_THUNK_P (thunk)) -    { -      error ("implementation-reserved name `%D' used", thunk_id); -      thunk = NULL_TREE; -      SET_IDENTIFIER_GLOBAL_VALUE (thunk_id, thunk); -    } -  if (thunk == NULL_TREE) -    { -      thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl)); -      DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (func_decl); -      cxx_dup_lang_specific_decl (func_decl); -      SET_DECL_ASSEMBLER_NAME (thunk, thunk_id); -      DECL_CONTEXT (thunk) = DECL_CONTEXT (func_decl); -      TREE_READONLY (thunk) = TREE_READONLY (func_decl); -      TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (func_decl); -      TREE_PUBLIC (thunk) = TREE_PUBLIC (func_decl); -      if (flag_weak) -	comdat_linkage (thunk); -      SET_DECL_THUNK_P (thunk); -      DECL_INITIAL (thunk) = function; -      THUNK_DELTA (thunk) = d; -      THUNK_VCALL_OFFSET (thunk) = vcall_offset; -      /* 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; -      /* And neither is it a clone.  */ -      DECL_CLONED_FUNCTION (thunk) = NULL_TREE; -      DECL_EXTERNAL (thunk) = 1; -      DECL_ARTIFICIAL (thunk) = 1; -      /* 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); -      SET_IDENTIFIER_GLOBAL_VALUE (thunk_id, thunk); -    }    return thunk;  } | 
