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]

(C++) patch: __check_null_eh_spec


This patch implements a special case for throw(), which saves space by losing

 1) The code to set up the args to __check_eh_spec
 2) The exception region stuff to handle an exception thrown from 
    __check_eh_spec

2000-03-11  Jason Merrill  <jason@casey.cygnus.com>

	* exception.cc (__check_null_eh_spec): New fn.
	* except.c (expand_end_eh_spec): Call it if the spec is throw().

Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/except.c,v
retrieving revision 1.102
diff -c -p -r1.102 except.c
*** except.c	2000/03/11 00:23:18	1.102
--- except.c	2000/03/11 08:55:24
*************** expand_end_eh_spec (raises, try_block)
*** 690,731 ****
    handler = begin_handler ();
    blocks = finish_handler_parms (NULL_TREE, handler);
  
!   /* Build up an array of type_infos.  */
!   for (; raises && TREE_VALUE (raises); raises = TREE_CHAIN (raises))
      {
!       types = tree_cons
! 	(NULL_TREE, build_eh_type_type (TREE_VALUE (raises)), types);
!       ++count;
      }
- 
-   types = build_nt (CONSTRUCTOR, NULL_TREE, types);
-   TREE_HAS_CONSTRUCTOR (types) = 1;
- 
-   /* We can't pass the CONSTRUCTOR directly, so stick it in a variable.  */
-   tmp = build_cplus_array_type (const_ptr_type_node, NULL_TREE);
-   decl = build_decl (VAR_DECL, NULL_TREE, tmp);
-   DECL_ARTIFICIAL (decl) = 1;
-   DECL_INITIAL (decl) = types;
-   DECL_CONTEXT (decl) = current_function_decl;
-   cp_finish_decl (decl, types, NULL_TREE, 0);
- 
-   decl = decay_conversion (decl);
- 
-   fn = get_identifier ("__check_eh_spec");
-   if (IDENTIFIER_GLOBAL_VALUE (fn))
-     fn = IDENTIFIER_GLOBAL_VALUE (fn);
    else
      {
!       tmp = tree_cons
! 	(NULL_TREE, integer_type_node, tree_cons
! 	 (NULL_TREE, TREE_TYPE (decl), void_list_node));
!       tmp = build_function_type (void_type_node, tmp);
  
!       fn = push_throw_library_fn (fn, tmp);
      }
  
-   tmp = tree_cons (NULL_TREE, build_int_2 (count, 0), 
- 		   tree_cons (NULL_TREE, decl, NULL_TREE));
    tmp = build_call (fn, tmp);
    finish_expr_stmt (tmp);
  
--- 690,750 ----
    handler = begin_handler ();
    blocks = finish_handler_parms (NULL_TREE, handler);
  
!   if (TREE_VALUE (raises) == NULL_TREE)
      {
!       fn = get_identifier ("__check_null_eh_spec");
!       if (IDENTIFIER_GLOBAL_VALUE (fn))
! 	fn = IDENTIFIER_GLOBAL_VALUE (fn);
!       else
! 	{
! 	  tmp = build_function_type (void_type_node, void_list_node);
! 	  fn = push_throw_library_fn (fn, tmp);
! 	  /* Since the spec doesn't allow any exceptions, this call
! 	     will never throw.  */
! 	  TREE_NOTHROW (fn) = 1;
! 	}
!       tmp = NULL_TREE;
      }
    else
      {
!       /* Build up an array of type_infos.  */
!       for (; raises && TREE_VALUE (raises); raises = TREE_CHAIN (raises))
! 	{
! 	  types = tree_cons
! 	    (NULL_TREE, build_eh_type_type (TREE_VALUE (raises)), types);
! 	  ++count;
! 	}
! 
!       types = build_nt (CONSTRUCTOR, NULL_TREE, types);
!       TREE_HAS_CONSTRUCTOR (types) = 1;
! 
!       /* We can't pass the CONSTRUCTOR directly, so stick it in a variable.  */
!       tmp = build_cplus_array_type (const_ptr_type_node, NULL_TREE);
!       decl = build_decl (VAR_DECL, NULL_TREE, tmp);
!       DECL_ARTIFICIAL (decl) = 1;
!       DECL_INITIAL (decl) = types;
!       DECL_CONTEXT (decl) = current_function_decl;
!       cp_finish_decl (decl, types, NULL_TREE, 0);
! 
!       decl = decay_conversion (decl);
! 
!       fn = get_identifier ("__check_eh_spec");
!       if (IDENTIFIER_GLOBAL_VALUE (fn))
! 	fn = IDENTIFIER_GLOBAL_VALUE (fn);
!       else
! 	{
! 	  tmp = tree_cons
! 	    (NULL_TREE, integer_type_node, tree_cons
! 	     (NULL_TREE, TREE_TYPE (decl), void_list_node));
! 	  tmp = build_function_type (void_type_node, tmp);
! 
! 	  fn = push_throw_library_fn (fn, tmp);
! 	}
  
!       tmp = tree_cons (NULL_TREE, build_int_2 (count, 0), 
! 		       tree_cons (NULL_TREE, decl, NULL_TREE));
      }
  
    tmp = build_call (fn, tmp);
    finish_expr_stmt (tmp);
  
Index: exception.cc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/exception.cc,v
retrieving revision 1.30
diff -c -p -r1.30 exception.cc
*** exception.cc	2000/03/08 17:16:17	1.30
--- exception.cc	2000/03/11 08:55:24
***************
*** 1,5 ****
  // Functions for Exception Support for -*- C++ -*-
! // Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation
  
  // This file is part of GNU CC.
  
--- 1,5 ----
  // Functions for Exception Support for -*- C++ -*-
! // Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation
  
  // This file is part of GNU CC.
  
*************** __check_eh_spec (int n, const void **spe
*** 319,324 ****
--- 319,332 ----
  
        terminate ();
      }
+ }
+ 
+ /* Special case of the above for throw() specs.  */
+ 
+ extern "C" void
+ __check_null_eh_spec (void)
+ {
+   __check_eh_spec (0, 0);
  }
  
  // Helpers for rtti. Although these don't return, we give them return types so

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