This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [csl-hpux-branch]: Use targetm structure for manglings


Zack Weinberg wrote:
Nathan Sidwell <nathan@codesourcery.com> writes:

Unfortunately there is a twisty interdependency on initializing the
mangler. Part needs to be done early and parts late.

I don't see why.  The table's initializer is entirely static data,
isn't it?
it has pointers to the global type node array, and relies on those
being initialized so it can get the TYPE_UID as a hash key.

Unfortunately part of the initialization sequence requires the
mangler's string buffer to be initialized before that point.

You can check in a patch that has the comment removed and the
initialization of builitin_type_manglings broken out of
write_builtin_type, whether or not that initialization function is
called lazily from write_builtin_type.
done with the attached.

nathan

--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
         The voices in my head said this was stupid too
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2003-12-12  Nathan Sidwell  <nathan@codesourcery.com>

	* target.h (gcc_target.abi): Add cxx_builtin_type_mangling.
	* target-def.h (TARGET_ABI_CXX_BUILTIN_TYPE_MANGLING): New.
	(TARGET_ABI): Add new initializer.
	* doc/tm.texi (TARGET_ABI_CXX_BUILTIN_TYPE_MANGLING): Document.
	* config/ia64/ia64.c (hpux_ia64_builtin_type_mangling): Override
	long_double_node mangling.

	* cp/mangle.c (integer_type_codes): Remove.
	(builtin_type_mangling_table): New.
	(struct builtin_type_mangling_entry): New.
	(builtin_type_manglings): New.
	(htab_builtin_type_hash, htab_builtin_type_eq): New.
	(builtin_type_mangling_init): New.
	(write_java_integer_type_codes): Remove.
	(write_builtin_type): Reimplement to use hash table and target
	specific overriders.

Index: target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.62.2.3
diff -c -3 -p -r1.62.2.3 target-def.h
*** target-def.h	10 Dec 2003 14:42:43 -0000	1.62.2.3
--- target-def.h	12 Dec 2003 18:29:14 -0000
*************** Foundation, 59 Temple Place - Suite 330,
*** 352,362 ****
--- 352,364 ----
  #define TARGET_ABI_CXX_VIRTUAL_DTORS_POSITION abi_cxx_vdp_default
  #define TARGET_ABI_CXX_EXPR_DECL_MANGLING abi_cxx_edm_default
  #define TARGET_ABI_CXX_DTOR_IN_CHARGE_PARM abi_cxx_dicp_default
+ #define TARGET_ABI_CXX_BUILTIN_TYPE_MANGLING NULL
  
  #define TARGET_ABI {						\
     TARGET_ABI_CXX_VIRTUAL_DTORS_POSITION,			\
     TARGET_ABI_CXX_EXPR_DECL_MANGLING,				\
     TARGET_ABI_CXX_DTOR_IN_CHARGE_PARM,				\
+    TARGET_ABI_CXX_BUILTIN_TYPE_MANGLING,			\
     }
  
  /* The whole shebang.  */
Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.70.2.3
diff -c -3 -p -r1.70.2.3 target.h
*** target.h	10 Dec 2003 14:42:45 -0000	1.70.2.3
--- target.h	12 Dec 2003 18:29:16 -0000
*************** struct gcc_target
*** 466,471 ****
--- 466,484 ----
        abi_cxx_dicp_always	  /* On every destructor.  */
      } cxx_dtor_in_charge_parm;
      
+     /* Override or augment builtin type mangling scheme. This is a
+        pointer to a NULL terminated array of struct.  */
+     const struct cxx_builtin_type_mangling 
+     {
+       /* Pointer to canonical type.  This must be the node one gets
+ 	 when building c_common_type_for_node.  We need a pointer to a
+ 	 type node to allow static initialization and PCH support.  */
+       tree *type_ptr;
+       
+       /* How to mangle it.  */
+       char mangling;
+     } *cxx_builtin_type_mangling;
+     
    } abi;
  };
  
Index: config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.259.2.3
diff -c -3 -p -r1.259.2.3 ia64.c
*** config/ia64/ia64.c	10 Dec 2003 14:42:51 -0000	1.259.2.3
--- config/ia64/ia64.c	12 Dec 2003 18:29:39 -0000
*************** static const struct attribute_spec ia64_
*** 386,391 ****
--- 386,402 ----
  #undef TARGET_ABI_CXX_DTOR_IN_CHARGE_PARM
  #define TARGET_ABI_CXX_DTOR_IN_CHARGE_PARM abi_cxx_dicp_always
  
+ /* On HPUX long double is mangled as 'g'.  */
+ static const struct cxx_builtin_type_mangling
+ hpux_ia64_builtin_type_manglings[] =
+ {
+   {&long_double_type_node, 'g'},
+   {NULL, 0}
+ };
+ 
+ #undef TARGET_ABI_CXX_BUILTIN_TYPE_MANGLING
+ #define TARGET_ABI_CXX_BUILTIN_TYPE_MANGLING hpux_ia64_builtin_type_manglings
+ 
  #endif
  
  struct gcc_target targetm = TARGET_INITIALIZER;
Index: cp/mangle.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/mangle.c,v
retrieving revision 1.88.6.2
diff -c -3 -p -r1.88.6.2 mangle.c
*** cp/mangle.c	30 Nov 2003 16:48:02 -0000	1.88.6.2
--- cp/mangle.c	12 Dec 2003 18:29:45 -0000
*************** substitution_identifier_index_t;
*** 127,150 ****
     once only.  */
  static GTY(()) tree subst_identifiers[SUBID_MAX];
  
! /* Single-letter codes for builtin integer types, defined in
!    <builtin-type>.  These are indexed by integer_type_kind values.  */
! static const char
! integer_type_codes[itk_none] =
! {
!   'c',  /* itk_char */
!   'a',  /* itk_signed_char */
!   'h',  /* itk_unsigned_char */
!   's',  /* itk_short */
!   't',  /* itk_unsigned_short */
!   'i',  /* itk_int */
!   'j',  /* itk_unsigned_int */
!   'l',  /* itk_long */
!   'm',  /* itk_unsigned_long */
!   'x',  /* itk_long_long */
!   'y'   /* itk_unsigned_long_long */
  };
  
  static int decl_is_template_id (const tree, tree* const);
  
  /* Functions for handling substitutions.  */
--- 127,186 ----
     once only.  */
  static GTY(()) tree subst_identifiers[SUBID_MAX];
  
! static const struct cxx_builtin_type_mangling
! builtin_type_mangling_table[] =
! {
!   {&void_type_node, 		'v'},
!   {&boolean_type_node,		'b'},
!   
!   /* Integral types.  */
!   {&char_type_node, 		'c'},
!   {&wchar_type_node, 		'w'},
!   {&signed_char_type_node, 	'a'},
!   {&unsigned_char_type_node,	'h'},
!   {&short_integer_type_node,	's'},
!   {&short_unsigned_type_node,	't'},
!   {&integer_type_node,		'i'},
!   {&unsigned_type_node,		'j'},
!   {&long_integer_type_node, 	'l'},
!   {&long_unsigned_type_node, 	'm'},
!   {&long_long_integer_type_node,  'x'},
!   {&long_long_unsigned_type_node, 'y'},
! #if HOST_BITS_PER_WIDE_INT >= 64
!   {&widest_integer_literal_type_node, 'n'},
!   {&widest_unsigned_literal_type_node, 'o'},
! #endif
!   
!   /* Float types.  */
!   {&float_type_node, 		'f'},
!   {&double_type_node, 		'd'},
!   {&long_double_type_node, 	'e'},
!   
!   /* Java integral types.  */
!   {&java_boolean_type_node,	'b'},
!   {&java_byte_type_node,	'c'},
!   {&java_char_type_node,	'w'},
!   {&java_short_type_node,	's'},
!   {&java_int_type_node,		'i'},
!   {&java_long_type_node,	'x'},
!   
!   /* Java float types.  */
!   {&java_float_type_node, 	'f'},
!   {&java_double_type_node,	'd'},
!   
!   {NULL, 0}
! };
! 
! struct builtin_type_mangling_entry GTY(())
! {
!   tree type;
!   char mangling;
  };
  
+ /* Hash table of scalar types.  */
+ static GTY ((param_is (struct builtin_type_mangling_entry)))
+      htab_t builtin_type_manglings = NULL;
+ 
  static int decl_is_template_id (const tree, tree* const);
  
  /* Functions for handling substitutions.  */
*************** static void write_special_name_construct
*** 182,187 ****
--- 218,226 ----
  static void write_special_name_destructor (const tree);
  static void write_type (tree);
  static int write_CV_qualifiers_for_type (const tree);
+ static hashval_t htab_builtin_type_hash (const void *);
+ static int htab_builtin_type_eq (const void *, const void *);
+ static void builtin_type_mangling_init (void);
  static void write_builtin_type (tree);
  static void write_function_type (const tree);
  static void write_bare_function_type (const tree, const int, const tree);
*************** static inline void start_mangling (const
*** 210,219 ****
  static inline const char *finish_mangling (const bool);
  static tree mangle_special_for_type (const tree, const char *);
  
- /* Foreign language functions.  */
- 
- static void write_java_integer_type_codes (const tree);
- 
  /* Append a single character to the end of the mangled
     representation.  */
  #define write_char(CHAR)                                              \
--- 249,254 ----
*************** write_CV_qualifiers_for_type (const tree
*** 1564,1569 ****
--- 1599,1681 ----
    return num_qualifiers;
  }
  
+ static hashval_t
+ htab_builtin_type_hash (const void *t_)
+ {
+   const struct builtin_type_mangling_entry *key = t_;
+ 
+   return (hashval_t)TYPE_UID (key->type);
+ }
+ 
+ static int
+ htab_builtin_type_eq (const void *t1_, const void *t2_)
+ {
+   const struct builtin_type_mangling_entry *key1 = t1_;
+   tree key2 = (tree)t2_;
+ 
+   return key1->type == key2;
+ }
+ 
+ /* Initialize the builtin type mangling table.  This must be done
+    lazily as it relies on the global type nodes to already have been
+    initialized.  */
+ 
+ static void
+ builtin_type_mangling_init ()
+ {
+   struct builtin_type_mangling_entry *mangling;
+   const struct cxx_builtin_type_mangling *def;
+ 
+   my_friendly_assert (!builtin_type_manglings, 20031212);
+   builtin_type_manglings = htab_create_ggc (20,
+ 					    htab_builtin_type_hash,
+ 					    htab_builtin_type_eq, NULL);
+ 
+   /* Install the default manglings.  */
+   for (def = builtin_type_mangling_table; def->type_ptr; def++)
+     {
+       struct builtin_type_mangling_entry **slot;
+       
+       slot = (struct builtin_type_mangling_entry **)
+ 	htab_find_slot_with_hash (builtin_type_manglings, *def->type_ptr,
+ 				  (hashval_t)TYPE_UID (*def->type_ptr),
+ 				  INSERT);
+       /* We shouldn't be overriding when inserting the default
+ 	 manglings.  */
+       my_friendly_assert (!*slot, 20031208);
+       mangling = ggc_alloc (sizeof (struct builtin_type_mangling_entry));
+       mangling->type = *def->type_ptr;
+       mangling->mangling = def->mangling;
+       *slot = mangling;
+     }
+   
+   /* Apply any target specific overriders.  */
+   if (targetm.abi.cxx_builtin_type_mangling)
+     for (def = targetm.abi.cxx_builtin_type_mangling; def->type_ptr; def++)
+       {
+ 	if (def->mangling)
+ 	  {
+ 	    struct builtin_type_mangling_entry **slot;
+ 	    
+ 	    slot = (struct builtin_type_mangling_entry **)
+ 	      htab_find_slot_with_hash (builtin_type_manglings, *def->type_ptr,
+ 					(hashval_t)TYPE_UID (*def->type_ptr),
+ 					INSERT);
+ 	    mangling = *slot;
+ 	    if (!mangling)
+ 	      {
+ 		mangling = 
+ 		  ggc_alloc (sizeof (struct builtin_type_mangling_entry));
+ 		mangling->type = *def->type_ptr;
+ 		*slot = mangling;
+ 	      }
+ 	    mangling->mangling = def->mangling;
+ 	  }
+ 	else
+ 	  htab_remove_elt (builtin_type_manglings, *def->type_ptr);
+       }
+ }
+ 
  /* Non-terminal <builtin-type>. 
  
       <builtin-type> ::= v   # void 
*************** write_CV_qualifiers_for_type (const tree
*** 1591,1669 ****
  static void 
  write_builtin_type (tree type)
  {
!   switch (TREE_CODE (type))
!     {
!     case VOID_TYPE:
!       write_char ('v');
!       break;
! 
!     case BOOLEAN_TYPE:
!       write_char ('b');
!       break;
  
!     case INTEGER_TYPE:
!       /* If this is size_t, get the underlying int type.  */
!       if (TYPE_IS_SIZETYPE (type))
! 	type = TYPE_DOMAIN (type);
! 
!       /* TYPE may still be wchar_t, since that isn't in
! 	 integer_type_nodes.  */
!       if (type == wchar_type_node)
! 	write_char ('w');
!       else if (TYPE_FOR_JAVA (type))
! 	write_java_integer_type_codes (type);
!       else
  	{
! 	  size_t itk;
! 	  /* Assume TYPE is one of the shared integer type nodes.  Find
! 	     it in the array of these nodes.  */
! 	iagain:
! 	  for (itk = 0; itk < itk_none; ++itk)
! 	    if (type == integer_types[itk])
! 	      {
! 		/* Print the corresponding single-letter code.  */
! 		write_char (integer_type_codes[itk]);
! 		break;
! 	      }
! 
! 	  if (itk == itk_none)
! 	    {
! 	      tree t = c_common_type_for_mode (TYPE_MODE (type),
! 					       TREE_UNSIGNED (type));
! 	      if (type == t)
! 		{
! 		  if (TYPE_PRECISION (type) == 128)
! 		    write_char (TREE_UNSIGNED (type) ? 'o' : 'n');
! 		  else
! 		    /* Couldn't find this type.  */
! 		    abort ();
! 		}
! 	      else
! 		{
! 		  type = t;
! 		  goto iagain;
! 		}
! 	    }
  	}
-       break;
- 
-     case REAL_TYPE:
-       if (type == float_type_node
- 	  || type == java_float_type_node)
- 	write_char ('f');
-       else if (type == double_type_node
- 	       || type == java_double_type_node)
- 	write_char ('d');
-       else if (type == long_double_type_node)
- 	/* HPUX uses 'g' for long double.  */
- 	write_char ('g');
        else
! 	abort ();
!       break;
! 
!     default:
        abort ();
      }
  }
  
  /* Non-terminal <function-type>.  NODE is a FUNCTION_TYPE or
--- 1703,1743 ----
  static void 
  write_builtin_type (tree type)
  {
!   struct builtin_type_mangling_entry *mangling;
  
!   if (!builtin_type_manglings)
!     builtin_type_mangling_init ();
!   
!   /* If this is size_t, get the underlying int type.  */
!   if (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type))
!     type = TYPE_DOMAIN (type);
!   
!  again:;
!   mangling = htab_find_with_hash (builtin_type_manglings,
! 				  type, (hashval_t)TYPE_UID (type));
!   if (mangling)
!     write_char (mangling->mangling);
!   else if (TREE_CODE (type) == INTEGER_TYPE)
!     {
!       tree t = c_common_type_for_mode (TYPE_MODE (type),
! 				       TREE_UNSIGNED (type));
!       if (type != t)
  	{
! 	  type = t;
! 	  goto again;
  	}
        else
! 	{
! 	  sorry ("cannot mangle %T", type);
! 	  abort ();
! 	}
!     }
!   else
!     {
!       sorry ("cannot mangle %T", type);
        abort ();
      }
+   
  }
  
  /* Non-terminal <function-type>.  NODE is a FUNCTION_TYPE or
*************** mangle_ref_init_variable (const tree var
*** 2730,2757 ****
    return get_identifier (finish_mangling (/*warn=*/false));
  }
  
- 
- /* Foreign language type mangling section.  */
- 
- /* How to write the type codes for the integer Java type.  */
- 
- static void
- write_java_integer_type_codes (const tree type)
- {
-   if (type == java_int_type_node)
-     write_char ('i');
-   else if (type == java_short_type_node)
-     write_char ('s');
-   else if (type == java_byte_type_node)
-     write_char ('c');
-   else if (type == java_char_type_node)
-     write_char ('w');
-   else if (type == java_long_type_node)
-     write_char ('x');
-   else if (type == java_boolean_type_node)
-     write_char ('b');
-   else
-     abort ();
- }
  
  #include "gt-cp-mangle.h"
--- 2804,2808 ----
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.266.2.3
diff -c -3 -p -r1.266.2.3 tm.texi
*** doc/tm.texi	10 Dec 2003 14:42:52 -0000	1.266.2.3
--- doc/tm.texi	12 Dec 2003 18:30:19 -0000
*************** parameter is passed immediately after th
*** 4542,4547 ****
--- 4542,4555 ----
  zero is passed.
  @end deftypevr
  
+ @deftypevr {Target Hook} {struct cxx_builtin_type_mangling} TARGET_ABI_CXX_BUILTIN_TYPE_MANGLING
+ Set this hook to augment or override the default mangling of the builtin
+ void, boolean, integral and floating point types.  When set the value
+ should be the name of an array of tuples.  The first is the address of
+ the cannonical type node and the second value is how to mangle it.  The
+ end of the array is denoted by a NULL type node address.
+ @end deftypevr
+ 
  @node Trampolines
  @section Trampolines for Nested Functions
  @cindex trampolines for nested functions

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]