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 to reorganize internal FUNCTION_DECL generation


The last patch caused me to notice how many different places in the
compiler are generating FUNCTION_DECLs.  This patch commonizes the
code in question.

I also deleted the middle parameter to build_call, since it can always be
extracted from the first parm.

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

	* decl.c (push_overloaded_decl_1, auto_function, 
	define_function): Lose.
	(build_library_fn_1): New static fn.
	(builtin_function): Use it.
	(get_atexit_node): Use build_library_fn_ptr.
	(build_library_fn, build_cp_library_fn, build_library_fn_ptr,
	build_cp_library_fn_ptr, push_library_fn, push_cp_library_fn,
	push_void_library_fn, push_throw_library_fn): New fns.
	* cp-tree.h: Declare them.
	(cp_tree_index): Remove CPTI_BAD_CAST, CPTI_BAD_TYPEID.
	(throw_bad_cast_node, throw_bad_typeid_node): Lose.
	* except.c (init_exception_processing, call_eh_info, do_pop_exception,
	(expand_end_eh_spec, alloc_eh_object, expand_throw): Use above fns.
	* rtti.c (build_runtime_decl): Lose.
	(throw_bad_cast, throw_bad_typeid, get_tinfo_decl, 
	build_dynamic_cast_1, expand_si_desc, expand_class_desc,
	expand_ptr_desc, expand_attr_desc, expand_generic_desc): Use above fns.

	* call.c (build_call): Remove result_type parm.
	Call mark_used on unused artificial fns.
	* init.c, method.c, typeck.c, except.c, rtti.c: Adjust.

Index: call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.202
diff -c -p -r1.202 call.c
*** call.c	2000/03/09 20:34:51	1.202
--- call.c	2000/03/10 09:14:19
*************** build_addr_func (function)
*** 364,376 ****
     (TYPE_PTRMEMFUNC_P) must be handled by our callers.  */
  
  tree
! build_call (function, result_type, parms)
!      tree function, result_type, parms;
  {
    int is_constructor = 0;
    int nothrow;
    tree tmp;
    tree decl;
  
    function = build_addr_func (function);
  
--- 364,377 ----
     (TYPE_PTRMEMFUNC_P) must be handled by our callers.  */
  
  tree
! build_call (function, parms)
!      tree function, parms;
  {
    int is_constructor = 0;
    int nothrow;
    tree tmp;
    tree decl;
+   tree result_type;
  
    function = build_addr_func (function);
  
*************** build_call (function, result_type, parms
*** 380,385 ****
--- 381,388 ----
        return error_mark_node;
      }
  
+   result_type = TREE_TYPE (TREE_TYPE (TREE_TYPE (function)));
+ 
    if (TREE_CODE (function) == ADDR_EXPR
        && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
      decl = TREE_OPERAND (function, 0);
*************** build_call (function, result_type, parms
*** 394,401 ****
    if (decl && DECL_CONSTRUCTOR_P (decl))
      is_constructor = 1;
  
!   if (decl)
!     my_friendly_assert (TREE_USED (decl), 990125);
  
    /* Don't pass empty class objects by value.  This is useful
       for tags in STL, which are used to control overload resolution.
--- 397,410 ----
    if (decl && DECL_CONSTRUCTOR_P (decl))
      is_constructor = 1;
  
!   if (decl && ! TREE_USED (decl))
!     {
!       /* We invoke build_call directly for several library functions.  */
!       if (DECL_ARTIFICIAL (decl))
! 	mark_used (decl);
!       else
! 	my_friendly_abort (990125);
!     }
  
    /* Don't pass empty class objects by value.  This is useful
       for tags in STL, which are used to control overload resolution.
*************** build_over_call (cand, args, flags)
*** 4157,4163 ****
  	return exp;
      }
  
!   fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args);
    if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE)
      return fn;
    fn = require_complete_type (fn);
--- 4166,4172 ----
  	return exp;
      }
  
!   fn = build_call (fn, converted_args);
    if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE)
      return fn;
    fn = require_complete_type (fn);
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.413
diff -c -p -r1.413 cp-tree.h
*** cp-tree.h	2000/03/05 10:22:16	1.413
--- cp-tree.h	2000/03/10 09:14:23
*************** enum cp_tree_index
*** 577,584 ****
      CPTI_TERMINATE,
      CPTI_ATEXIT,
      CPTI_DSO_HANDLE,
-     CPTI_BAD_CAST,
-     CPTI_BAD_TYPEID,
      CPTI_DCAST,
  
      CPTI_MAX
--- 577,582 ----
*************** extern tree cp_global_trees[CPTI_MAX];
*** 686,697 ****
  /* A pointer to `__dso_handle'.  */
  #define dso_handle_node                 cp_global_trees[CPTI_DSO_HANDLE]
  
- /* The declaration of __throw_bad_cast.  */
- #define throw_bad_cast_node             cp_global_trees[CPTI_BAD_CAST]
- 
- /* The declaration of __throw_bad_typeid.  */
- #define throw_bad_typeid_node           cp_global_trees[CPTI_BAD_TYPEID]
- 
  /* The declaration of the dynamic_cast runtime.  */
  #define dynamic_cast_node               cp_global_trees[CPTI_DCAST]
  
--- 684,689 ----
*************** extern tree build_vfield_ref			PARAMS ((
*** 3605,3611 ****
  extern tree resolve_scope_to_name		PARAMS ((tree, tree));
  extern tree build_scoped_method_call		PARAMS ((tree, tree, tree, tree));
  extern tree build_addr_func			PARAMS ((tree));
! extern tree build_call				PARAMS ((tree, tree, tree));
  extern tree build_method_call			PARAMS ((tree, tree, tree, tree, int));
  extern int null_ptr_cst_p			PARAMS ((tree));
  extern tree type_decays_to			PARAMS ((tree));
--- 3597,3603 ----
  extern tree resolve_scope_to_name		PARAMS ((tree, tree));
  extern tree build_scoped_method_call		PARAMS ((tree, tree, tree, tree));
  extern tree build_addr_func			PARAMS ((tree));
! extern tree build_call				PARAMS ((tree, tree));
  extern tree build_method_call			PARAMS ((tree, tree, tree, tree, int));
  extern int null_ptr_cst_p			PARAMS ((tree));
  extern tree type_decays_to			PARAMS ((tree));
*************** extern tree namespace_ancestor			PARAMS 
*** 3753,3764 ****
  extern tree unqualified_namespace_lookup	PARAMS ((tree, int, tree *));
  extern int  lookup_using_namespace              PARAMS ((tree, tree, tree, tree, int, tree *));
  extern int  qualified_lookup_using_namespace    PARAMS ((tree, tree, tree, int));
! extern tree auto_function			PARAMS ((tree, tree));
  extern void init_decl_processing		PARAMS ((void));
  extern int init_type_desc			PARAMS ((void));
- extern tree define_function			PARAMS ((const char *, tree,
- 						       void (*) (tree),
- 						       const char *));
  extern tree check_tag_decl			PARAMS ((tree));
  extern void shadow_tag				PARAMS ((tree));
  extern tree groktypename			PARAMS ((tree));
--- 3745,3760 ----
  extern tree unqualified_namespace_lookup	PARAMS ((tree, int, tree *));
  extern int  lookup_using_namespace              PARAMS ((tree, tree, tree, tree, int, tree *));
  extern int  qualified_lookup_using_namespace    PARAMS ((tree, tree, tree, int));
! extern tree build_library_fn			PARAMS ((tree, tree));
! extern tree build_cp_library_fn			PARAMS ((tree, tree));
! extern tree build_library_fn_ptr		PARAMS ((const char *, tree));
! extern tree build_cp_library_fn_ptr		PARAMS ((const char *, tree));
! extern tree push_library_fn			PARAMS ((tree, tree));
! extern tree push_cp_library_fn			PARAMS ((tree, tree));
! extern tree push_void_library_fn		PARAMS ((tree, tree));
! extern tree push_throw_library_fn		PARAMS ((tree, tree));
  extern void init_decl_processing		PARAMS ((void));
  extern int init_type_desc			PARAMS ((void));
  extern tree check_tag_decl			PARAMS ((tree));
  extern void shadow_tag				PARAMS ((tree));
  extern tree groktypename			PARAMS ((tree));
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.561
diff -c -p -r1.561 decl.c
*** decl.c	2000/03/09 20:34:51	1.561
--- decl.c	2000/03/10 09:14:34
*************** static void declare_namespace_level PARA
*** 113,119 ****
  static void signal_catch PARAMS ((int)) ATTRIBUTE_NORETURN;
  static void storedecls PARAMS ((tree));
  static void require_complete_types_for_parms PARAMS ((tree));
- static void push_overloaded_decl_1 PARAMS ((tree));
  static int ambi_op_p PARAMS ((tree));
  static int unary_op_p PARAMS ((tree));
  static tree store_bindings PARAMS ((tree, tree));
--- 113,118 ----
*************** static void set_identifier_type_value_wi
*** 133,138 ****
--- 132,138 ----
  	PARAMS ((tree, tree, struct binding_level *));
  static void record_builtin_type PARAMS ((enum rid, const char *, tree));
  static void record_unknown_type PARAMS ((tree, const char *));
+ static tree build_library_fn_1			PARAMS ((tree, tree));
  static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
  static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
  				  int));
*************** record_unknown_type (type, name)
*** 5937,5962 ****
    TYPE_MODE (type) = TYPE_MODE (void_type_node);
  }
  
- /* Push overloaded decl, in global scope, with one argument so it
-    can be used as a callback from define_function.  */
- 
- static void
- push_overloaded_decl_1 (x)
-      tree x;
- {
-   pushdecl (x);
- }
- 
- inline tree
- auto_function (name, type)
-      tree name, type;
- {
-   return define_function
-     (IDENTIFIER_POINTER (name), type, push_overloaded_decl_1,
-      IDENTIFIER_POINTER (build_decl_overload (name, TYPE_ARG_TYPES (type),
- 					      0)));
- }
- 
  /* Create the predefined scalar types of C,
     and some nodes representing standard constants (0, 1, (void *)0).
     Initialize the global binding level.
--- 5937,5942 ----
*************** init_decl_processing ()
*** 6320,6334 ****
      newtype = build_exception_variant
        (ptr_ftype_sizetype, add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1));
      deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
!     auto_function (ansi_opname[(int) NEW_EXPR], newtype);
!     auto_function (ansi_opname[(int) VEC_NEW_EXPR], newtype);
!     global_delete_fndecl = auto_function (ansi_opname[(int) DELETE_EXPR],
! 					  deltype);
!     auto_function (ansi_opname[(int) VEC_DELETE_EXPR], deltype);
    }
  
    abort_fndecl
!     = define_function ("__pure_virtual", void_ftype, 0, 0);
  
    /* Perform other language dependent initializations.  */
    init_class_processing ();
--- 6300,6314 ----
      newtype = build_exception_variant
        (ptr_ftype_sizetype, add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1));
      deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
!     push_cp_library_fn (ansi_opname[(int) NEW_EXPR], newtype);
!     push_cp_library_fn (ansi_opname[(int) VEC_NEW_EXPR], newtype);
!     global_delete_fndecl = push_cp_library_fn (ansi_opname[(int) DELETE_EXPR],
! 					       deltype);
!     push_cp_library_fn (ansi_opname[(int) VEC_DELETE_EXPR], deltype);
    }
  
    abort_fndecl
!     = build_library_fn_ptr ("__pure_virtual", void_ftype);
  
    /* Perform other language dependent initializations.  */
    init_class_processing ();
*************** lang_print_error_function (file)
*** 6461,6520 ****
    maybe_print_template_context ();
  }
  
! /* Make a definition for a builtin function named NAME and whose data type
     is TYPE.  TYPE should be a function type with argument types.
  
!    If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
     the name to be called if we can't opencode the function.  */
  
  tree
! define_function (name, type, pfn, library_name)
       const char *name;
       tree type;
!      void (*pfn) PARAMS ((tree));
!      const char *library_name;
  {
!   tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type);
!   DECL_EXTERNAL (decl) = 1;
!   TREE_PUBLIC (decl) = 1;
!   DECL_ARTIFICIAL (decl) = 1;
! 
!   /* If no exception specifier was given, assume it doesn't throw.  */
!   if (TYPE_RAISES_EXCEPTIONS (type) == NULL_TREE)
!     TREE_NOTHROW (decl) = 1;
  
    my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392);
-   DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
  
    /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
       we cannot change DECL_ASSEMBLER_NAME until we have installed this
       function in the namespace.  */
!   if (pfn) (*pfn) (decl);
!   if (library_name)
!     DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
    make_function_rtl (decl);
    return decl;
  }
  
  
! /* Wrapper around define_function, for the benefit of
!    c_common_nodes_and_builtins.
!    FUNCTION_CODE tells later passes how to compile calls to this function.
!    See tree.h for its possible values.  */
  
  tree
! builtin_function (name, type, code, class, libname)
       const char *name;
       tree type;
-      int code;
-      enum built_in_class class;
-      const char *libname;
  {
!   tree decl = define_function (name, type, (void (*) PARAMS ((tree)))pushdecl,
! 			       libname);
!   DECL_BUILT_IN_CLASS (decl) = class;
!   DECL_FUNCTION_CODE (decl) = code;
!   return decl;
  }
  
  /* When we call finish_struct for an anonymous union, we create
--- 6441,6594 ----
    maybe_print_template_context ();
  }
  
! /* Entry point for the benefit of c_common_nodes_and_builtins.
! 
!    Make a definition for a builtin function named NAME and whose data type
     is TYPE.  TYPE should be a function type with argument types.
+ 
+    CLASS and CODE tell later passes how to compile calls to this function.
+    See tree.h for possible values.
  
!    If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME,
     the name to be called if we can't opencode the function.  */
  
  tree
! builtin_function (name, type, code, class, libname)
       const char *name;
       tree type;
!      int code;
!      enum built_in_class class;
!      const char *libname;
  {
!   tree decl = build_library_fn_1 (get_identifier (name), type);
!   DECL_BUILT_IN_CLASS (decl) = class;
!   DECL_FUNCTION_CODE (decl) = code;
  
    my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392);
  
    /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
       we cannot change DECL_ASSEMBLER_NAME until we have installed this
       function in the namespace.  */
!   pushdecl (decl);
!   if (libname)
!     DECL_ASSEMBLER_NAME (decl) = get_identifier (libname);
    make_function_rtl (decl);
    return decl;
  }
  
+ /* Generate a FUNCTION_DECL with the typical flags for a runtime library
+    function.  Not called directly.  */
+ 
+ static tree
+ build_library_fn_1 (name, type)
+      tree name;
+      tree type;
+ {
+   tree fn = build_lang_decl (FUNCTION_DECL, name, type);
+   DECL_EXTERNAL (fn) = 1;
+   TREE_PUBLIC (fn) = 1;
+   DECL_ARTIFICIAL (fn) = 1;
+   TREE_NOTHROW (fn) = 1;
+   return fn;
+ }
  
! /* Returns the _DECL for a library function with C linkage.
!    We assume that such functions never throw; if this is incorrect,
!    callers should unset TREE_NOTHROW.  */
  
  tree
! build_library_fn (name, type)
!      tree name;
!      tree type;
! {
!   tree fn = build_library_fn_1 (name, type);
!   make_function_rtl (fn);
!   return fn;
! }
! 
! /* Returns the _DECL for a library function with C++ linkage.  */
! 
! tree
! build_cp_library_fn (name, type)
!      tree name;
!      tree type;
! {
!   tree fn = build_library_fn_1 (name, type);
!   TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
!   set_mangled_name_for_decl (fn);
!   make_function_rtl (fn);
!   return fn;
! }
! 
! /* Like build_library_fn, but takes a C string instead of an
!    IDENTIFIER_NODE.  */
! 
! tree
! build_library_fn_ptr (name, type)
       const char *name;
       tree type;
  {
!   return build_library_fn (get_identifier (name), type);
! }
! 
! /* Like build_cp_library_fn, but takes a C string instead of an
!    IDENTIFIER_NODE.  */
! 
! tree
! build_cp_library_fn_ptr (name, type)
!      const char *name;
!      tree type;
! {
!   return build_cp_library_fn (get_identifier (name), type);
! }
! 
! /* Like build_library_fn, but also pushes the function so that we will
!    be able to find it via IDENTIFIER_GLOBAL_VALUE.  */
! 
! tree
! push_library_fn (name, type)
!      tree name, type;
! {
!   tree fn = build_library_fn (name, type);
!   pushdecl_top_level (fn);
!   return fn;
! }
! 
! /* Like build_cp_library_fn, but also pushes the function so that it
!    will be found by normal lookup.  */
! 
! tree
! push_cp_library_fn (name, type)
!      tree name;
!      tree type;
! {
!   tree fn = build_cp_library_fn (name, type);
!   pushdecl (fn);
!   return fn;
! }
! 
! /* Like push_library_fn, but takes a TREE_LIST of parm types rather than
!    a FUNCTION_TYPE.  */
! 
! tree
! push_void_library_fn (name, parmtypes)
!      tree name, parmtypes;
! {
!   tree type = build_function_type (void_type_node, parmtypes);
!   return push_library_fn (name, type);
! }
! 
! /* Like push_void_library_fn, but also note that this function throws
!    and does not return.  Used for __throw_foo and the like.  */
! 
! tree
! push_throw_library_fn (name, parmtypes)
!      tree name, parmtypes;
! {
!   tree fn = push_void_library_fn (name, parmtypes);
!   TREE_THIS_VOLATILE (fn) = 1;
!   TREE_NOTHROW (fn) = 0;
!   return fn;
  }
  
  /* When we call finish_struct for an anonymous union, we create
*************** get_atexit_node ()
*** 7984,7990 ****
  
    /* Now, build the function declaration.  */
    push_lang_context (lang_name_c);
!   atexit_fndecl = define_function (name, fn_type, /*pfn=*/0, NULL_PTR);
    mark_used (atexit_fndecl);
    pop_lang_context ();
    atexit_node = default_conversion (atexit_fndecl);
--- 8058,8064 ----
  
    /* Now, build the function declaration.  */
    push_lang_context (lang_name_c);
!   atexit_fndecl = build_library_fn_ptr (name, fn_type);
    mark_used (atexit_fndecl);
    pop_lang_context ();
    atexit_node = default_conversion (atexit_fndecl);
Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/except.c,v
retrieving revision 1.99
diff -c -p -r1.99 except.c
*** except.c	2000/03/09 20:34:52	1.99
--- except.c	2000/03/10 09:14:39
*************** init_exception_processing ()
*** 173,180 ****
    
    if (flag_honor_std)
      push_namespace (get_identifier ("std"));
!   terminate_node = auto_function (get_identifier ("terminate"), vtype);
    TREE_THIS_VOLATILE (terminate_node) = 1;
    if (flag_honor_std)
      pop_namespace ();
  
--- 173,181 ----
    
    if (flag_honor_std)
      push_namespace (get_identifier ("std"));
!   terminate_node = build_cp_library_fn_ptr ("terminate", vtype);
    TREE_THIS_VOLATILE (terminate_node) = 1;
+   TREE_NOTHROW (terminate_node) = 1;
    if (flag_honor_std)
      pop_namespace ();
  
*************** call_eh_info ()
*** 253,268 ****
        t = build_pointer_type (t);
  
        /* And now the function.  */
!       fn = build_lang_decl (FUNCTION_DECL, fn,
! 			    build_function_type (t, void_list_node));
!       DECL_EXTERNAL (fn) = 1;
!       TREE_PUBLIC (fn) = 1;
!       DECL_ARTIFICIAL (fn) = 1;
!       TREE_NOTHROW (fn) = 1;
!       pushdecl_top_level (fn);
!       make_function_rtl (fn);
      }
-   mark_used (fn);
    return build_function_call (fn, NULL_TREE);
  }
  
--- 254,261 ----
        t = build_pointer_type (t);
  
        /* And now the function.  */
!       fn = push_library_fn (fn, build_function_type (t, void_list_node));
      }
    return build_function_call (fn, NULL_TREE);
  }
  
*************** do_pop_exception ()
*** 424,441 ****
      {
        /* Declare void __cp_pop_exception (void *),
  	 as defined in exception.cc. */
!       fn = build_lang_decl
! 	(FUNCTION_DECL, fn,
! 	 build_function_type (void_type_node, tree_cons
! 			      (NULL_TREE, ptr_type_node, void_list_node)));
!       DECL_EXTERNAL (fn) = 1;
!       TREE_PUBLIC (fn) = 1;
!       DECL_ARTIFICIAL (fn) = 1;
!       pushdecl_top_level (fn);
!       make_function_rtl (fn);
      }
  
-   mark_used (fn);
    /* Arrange to do a dynamically scoped cleanup upon exit from this region.  */
    cleanup = lookup_name (get_identifier ("__exception_info"), 0);
    cleanup = build_function_call (fn, tree_cons
--- 417,428 ----
      {
        /* Declare void __cp_pop_exception (void *),
  	 as defined in exception.cc. */
!       fn = push_void_library_fn
! 	(fn, tree_cons (NULL_TREE, ptr_type_node, void_list_node));
!       /* This can throw if the destructor for the exception throws.  */
!       TREE_NOTHROW (fn) = 0;
      }
  
    /* Arrange to do a dynamically scoped cleanup upon exit from this region.  */
    cleanup = lookup_name (get_identifier ("__exception_info"), 0);
    cleanup = build_function_call (fn, tree_cons
*************** expand_end_eh_spec (raises, try_block)
*** 732,752 ****
        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 = build_lang_decl (FUNCTION_DECL, fn, tmp);
!       DECL_EXTERNAL (fn) = 1;
!       TREE_PUBLIC (fn) = 1;
!       DECL_ARTIFICIAL (fn) = 1;
!       TREE_THIS_VOLATILE (fn) = 1;
!       pushdecl_top_level (fn);
!       make_function_rtl (fn);
      }
  
-   mark_used (fn);
    tmp = tree_cons (NULL_TREE, build_int_2 (count, 0), 
  		   tree_cons (NULL_TREE, decl, NULL_TREE));
!   tmp = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), tmp);
    finish_expr_stmt (tmp);
  
    finish_handler (blocks, handler);
--- 719,731 ----
        tmp = tree_cons
  	(NULL_TREE, integer_type_node, tree_cons
  	 (NULL_TREE, TREE_TYPE (decl), void_list_node));
! 
!       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);
  
    finish_handler (blocks, handler);
*************** alloc_eh_object (type)
*** 799,817 ****
    else
      {
        /* Declare __eh_alloc (size_t), as defined in exception.cc.  */
!       tree tmp;
!       tmp = tree_cons (NULL_TREE, sizetype, void_list_node);
!       fn = build_lang_decl (FUNCTION_DECL, fn,
! 			    build_function_type (ptr_type_node, tmp));
!       DECL_EXTERNAL (fn) = 1;
!       TREE_PUBLIC (fn) = 1;
!       DECL_ARTIFICIAL (fn) = 1;
!       TREE_NOTHROW (fn) = 1;
!       pushdecl_top_level (fn);
!       make_function_rtl (fn);
      }
  
-   mark_used (fn);
    exp = build_function_call (fn, tree_cons
  			     (NULL_TREE, size_in_bytes (type), NULL_TREE));
    exp = build1 (NOP_EXPR, build_pointer_type (type), exp);
--- 778,787 ----
    else
      {
        /* Declare __eh_alloc (size_t), as defined in exception.cc.  */
!       tree tmp = tree_cons (NULL_TREE, sizetype, void_list_node);
!       fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
      }
  
    exp = build_function_call (fn, tree_cons
  			     (NULL_TREE, size_in_bytes (type), NULL_TREE));
    exp = build1 (NOP_EXPR, build_pointer_type (type), exp);
*************** expand_throw (exp)
*** 852,867 ****
  	{
  	  /* Declare _Jv_Throw (void *), as defined in Java's
  	     exception.cc.  */
! 	  tree tmp;
! 	  tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
! 	  fn = build_lang_decl (FUNCTION_DECL, fn,
! 				build_function_type (ptr_type_node, tmp));
! 	  DECL_EXTERNAL (fn) = 1;
! 	  TREE_PUBLIC (fn) = 1;
! 	  DECL_ARTIFICIAL (fn) = 1;
  	  TREE_THIS_VOLATILE (fn) = 1;
! 	  pushdecl_top_level (fn);
! 	  make_function_rtl (fn);
  	}
  
        exp = build_function_call (fn, args);
--- 822,832 ----
  	{
  	  /* Declare _Jv_Throw (void *), as defined in Java's
  	     exception.cc.  */
! 	  tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
! 	  tmp = build_function_type (ptr_type_node, tmp);
! 	  fn = push_library_fn (fn, tmp);
  	  TREE_THIS_VOLATILE (fn) = 1;
! 	  TREE_NOTHROW (fn) = 0;
  	}
  
        exp = build_function_call (fn, args);
*************** expand_throw (exp)
*** 974,990 ****
  	    (NULL_TREE, ptr_type_node, tree_cons
  	     (NULL_TREE, ptr_type_node, tree_cons
  	      (NULL_TREE, cleanup_type, void_list_node)));
! 	  fn = build_lang_decl (FUNCTION_DECL, fn,
! 				build_function_type (void_type_node, tmp));
! 	  DECL_EXTERNAL (fn) = 1;
! 	  TREE_PUBLIC (fn) = 1;
! 	  DECL_ARTIFICIAL (fn) = 1;
! 	  TREE_NOTHROW (fn) = 1;
! 	  pushdecl_top_level (fn);
! 	  make_function_rtl (fn);
  	}
  
-       mark_used (fn);
        e = tree_cons (NULL_TREE, exp, tree_cons
  		     (NULL_TREE, throw_type, tree_cons
  		      (NULL_TREE, cleanup, NULL_TREE)));
--- 939,947 ----
  	    (NULL_TREE, ptr_type_node, tree_cons
  	     (NULL_TREE, ptr_type_node, tree_cons
  	      (NULL_TREE, cleanup_type, void_list_node)));
! 	  fn = push_void_library_fn (fn, tmp);
  	}
  
        e = tree_cons (NULL_TREE, exp, tree_cons
  		     (NULL_TREE, throw_type, tree_cons
  		      (NULL_TREE, cleanup, NULL_TREE)));
*************** expand_throw (exp)
*** 1000,1020 ****
        if (IDENTIFIER_GLOBAL_VALUE (fn))
  	fn = IDENTIFIER_GLOBAL_VALUE (fn);
        else
! 	{
! 	  /* Declare void __uncatch_exception (void)
! 	     as defined in exception.cc. */
! 	  fn = build_lang_decl (FUNCTION_DECL, fn,
! 				build_function_type (void_type_node,
! 						     void_list_node));
! 	  DECL_EXTERNAL (fn) = 1;
! 	  TREE_PUBLIC (fn) = 1;
! 	  DECL_ARTIFICIAL (fn) = 1;
! 	  TREE_NOTHROW (fn) = 1;
! 	  pushdecl_top_level (fn);
! 	  make_function_rtl (fn);
! 	}
  
-       mark_used (fn);
        exp = build_function_call (fn, NULL_TREE);
      }
  
--- 957,966 ----
        if (IDENTIFIER_GLOBAL_VALUE (fn))
  	fn = IDENTIFIER_GLOBAL_VALUE (fn);
        else
! 	/* Declare void __uncatch_exception (void)
! 	   as defined in exception.cc. */
! 	fn = push_void_library_fn (fn, void_list_node);
  
        exp = build_function_call (fn, NULL_TREE);
      }
  
Index: init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v
retrieving revision 1.173
diff -c -p -r1.173 init.c
*** init.c	2000/03/07 11:41:21	1.173
--- init.c	2000/03/10 09:16:44
*************** build_builtin_delete_call (addr)
*** 1868,1875 ****
       tree addr;
  {
    mark_used (global_delete_fndecl);
!   return build_call (global_delete_fndecl, 
! 		     void_type_node, build_tree_list (NULL_TREE, addr));
  }
  
  /* Generate a C++ "new" expression. DECL is either a TREE_LIST
--- 1868,1874 ----
       tree addr;
  {
    mark_used (global_delete_fndecl);
!   return build_call (global_delete_fndecl, build_tree_list (NULL_TREE, addr));
  }
  
  /* Generate a C++ "new" expression. DECL is either a TREE_LIST
Index: method.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/method.c,v
retrieving revision 1.140
diff -c -p -r1.140 method.c
*** method.c	2000/03/07 20:39:07	1.140
--- method.c	2000/03/10 09:16:45
*************** emit_thunk (thunk_fndecl)
*** 2156,2162 ****
      for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
        t = tree_cons (NULL_TREE, a, t);
      t = nreverse (t);
!     t = build_call (function, TREE_TYPE (TREE_TYPE (function)), t);
      finish_return_stmt (t);
  
      expand_body (finish_function (lineno, 0));
--- 2156,2162 ----
      for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
        t = tree_cons (NULL_TREE, a, t);
      t = nreverse (t);
!     t = build_call (function, t);
      finish_return_stmt (t);
  
      expand_body (finish_function (lineno, 0));
Index: rtti.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/rtti.c,v
retrieving revision 1.64
diff -c -p -r1.64 rtti.c
*** rtti.c	2000/03/09 20:34:52	1.64
--- rtti.c	2000/03/10 09:16:47
*************** Boston, MA 02111-1307, USA.  */
*** 45,51 ****
  
  extern struct obstack permanent_obstack;
  
- static tree build_runtime_decl PARAMS((const char *, tree));
  static tree build_headof_sub PARAMS((tree));
  static tree build_headof PARAMS((tree));
  static tree get_tinfo_var PARAMS((tree));
--- 45,50 ----
*************** build_headof (exp)
*** 165,199 ****
  		cp_convert (ptrdiff_type_node, offset));
  }
  
- /* Build a decl to a runtime entry point taking void and returning TYPE. 
-    Although the entry point may never return, making its return type
-    consistent is necessary.  */
- 
- static tree
- build_runtime_decl (name, type)
-      const char *name;
-      tree type;
- {
-   tree d = get_identifier (name);
-   
-   if (IDENTIFIER_GLOBAL_VALUE (d))
-     d = IDENTIFIER_GLOBAL_VALUE (d);
-   else
-     {
-       type = build_function_type (type, void_list_node);
-       d = build_lang_decl (FUNCTION_DECL, d, type);
-       DECL_EXTERNAL (d) = 1;
-       TREE_PUBLIC (d) = 1;
-       DECL_ARTIFICIAL (d) = 1;
-       TREE_THIS_VOLATILE (d) = 1;
-       pushdecl_top_level (d);
-       make_function_rtl (d);
-     }
- 
-   mark_used (d);
-   return d;
- }
- 
  /* Get a bad_cast node for the program to throw...
  
     See libstdc++/exception.cc for __throw_bad_cast */
--- 164,169 ----
*************** build_runtime_decl (name, type)
*** 201,228 ****
  static tree
  throw_bad_cast ()
  {
!   if (!throw_bad_cast_node)
!     throw_bad_cast_node = build_runtime_decl
!         ("__throw_bad_cast", ptr_type_node);
    
!   return build_call (throw_bad_cast_node,
!                      TREE_TYPE (TREE_TYPE (throw_bad_cast_node)),
!                      NULL_TREE);
  }
  
  static tree
  throw_bad_typeid ()
  {
!   if (!throw_bad_typeid_node)
!     throw_bad_typeid_node = build_runtime_decl
!         ("__throw_bad_typeid",
!          build_reference_type
!           (build_qualified_type
!             (type_info_type_node, TYPE_QUAL_CONST)));
  
!   return build_call (throw_bad_typeid_node,
!                      TREE_TYPE (TREE_TYPE (throw_bad_typeid_node)),
!                      NULL_TREE);
  }
  
  /* Return a pointer to type_info function associated with the expression EXP.
--- 171,197 ----
  static tree
  throw_bad_cast ()
  {
!   tree fn = get_identifier ("__throw_bad_cast");
!   if (IDENTIFIER_GLOBAL_VALUE (fn))
!     fn = IDENTIFIER_GLOBAL_VALUE (fn);
!   else
!     fn = push_throw_library_fn (fn, ptr_type_node);
    
!   return build_call (fn, NULL_TREE);
  }
  
  static tree
  throw_bad_typeid ()
  {
!   tree fn = get_identifier ("__throw_bad_cast");
!   if (IDENTIFIER_GLOBAL_VALUE (fn))
!     fn = IDENTIFIER_GLOBAL_VALUE (fn);
!   else
!     fn = push_throw_library_fn (fn, build_reference_type
! 				(build_qualified_type
! 				 (type_info_type_node, TYPE_QUAL_CONST)));
  
!   return build_call (fn, NULL_TREE);
  }
  
  /* Return a pointer to type_info function associated with the expression EXP.
*************** get_tinfo_decl (type)
*** 420,436 ****
      {
        /* The tinfo decl is a function returning a reference to the type_info
           object.  */
!       d = build_lang_decl (FUNCTION_DECL, name, tinfo_decl_type);
!       DECL_EXTERNAL (d) = 1;
!       TREE_PUBLIC (d) = 1;
!       DECL_ARTIFICIAL (d) = 1;
!       TREE_NOTHROW (d) = 1;
        DECL_NOT_REALLY_EXTERN (d) = 1;
        SET_DECL_TINFO_FN_P (d);
        TREE_TYPE (name) = type;
- 
-       pushdecl_top_level (d);
-       make_function_rtl (d);
        mark_inline_for_output (d);
      }
    else
--- 389,398 ----
      {
        /* The tinfo decl is a function returning a reference to the type_info
           object.  */
!       d = push_library_fn (name, tinfo_decl_type);
        DECL_NOT_REALLY_EXTERN (d) = 1;
        SET_DECL_TINFO_FN_P (d);
        TREE_TYPE (name) = type;
        mark_inline_for_output (d);
      }
    else
*************** tinfo_from_decl (expr)
*** 468,474 ****
    tree t;
    
    if (!new_abi_rtti_p ())
!     t = build_call (expr, TREE_TYPE (tinfo_decl_type), NULL_TREE);
    else if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
      t = build_indirect_ref (expr, NULL);
    else
--- 430,436 ----
    tree t;
    
    if (!new_abi_rtti_p ())
!     t = build_call (expr, NULL_TREE);
    else if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
      t = build_indirect_ref (expr, NULL);
    else
*************** build_dynamic_cast_1 (type, expr)
*** 814,837 ****
  	                  (NULL_TREE, ptrdiff_type_node, void_list_node))));
  	        }
  	      tmp = build_function_type (ptr_type_node, tmp);
- 	      dcast_fn = build_lang_decl (FUNCTION_DECL,
- 	                                  get_identifier (name),
- 	                                  tmp);
- 	      DECL_EXTERNAL (dcast_fn) = 1;
- 	      TREE_PUBLIC (dcast_fn) = 1;
- 	      DECL_ARTIFICIAL (dcast_fn) = 1;
- 	      TREE_NOTHROW (dcast_fn) = 1;
- 	      pushdecl (dcast_fn);
  	      if (new_abi_rtti_p ())
! 	        /* We want its name mangling.  */
! 	        set_mangled_name_for_decl (dcast_fn);
! 	      make_function_rtl (dcast_fn);
                pop_nested_namespace (ns);
                dynamic_cast_node = dcast_fn;
  	    }
! 	  mark_used (dcast_fn);
!           result = build_call
! 	    (dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
  
  	  if (tc == REFERENCE_TYPE)
  	    {
--- 776,790 ----
  	                  (NULL_TREE, ptrdiff_type_node, void_list_node))));
  	        }
  	      tmp = build_function_type (ptr_type_node, tmp);
  	      if (new_abi_rtti_p ())
! 		/* We want its name mangling.  */
! 		dcast_fn = build_cp_library_fn_ptr (name, tmp);
! 	      else
! 		dcast_fn = build_library_fn_ptr (name, tmp);
                pop_nested_namespace (ns);
                dynamic_cast_node = dcast_fn;
  	    }
!           result = build_call (dcast_fn, elems);
  
  	  if (tc == REFERENCE_TYPE)
  	    {
*************** expand_si_desc (tdecl, type)
*** 912,930 ****
  	 (NULL_TREE, const_string_type_node, tree_cons
  	  (NULL_TREE, build_pointer_type (type_info_type_node),
  	   void_list_node)));
!       tmp = build_function_type	(void_type_node, tmp);
!   
!       fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
!       DECL_EXTERNAL (fn) = 1;
!       TREE_PUBLIC (fn) = 1;
!       DECL_ARTIFICIAL (fn) = 1;
!       TREE_NOTHROW (fn) = 1;
!       pushdecl_top_level (fn);
!       make_function_rtl (fn);
      }
  
!   mark_used (fn);
!   fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
    finish_expr_stmt (fn);
  }
  
--- 865,874 ----
  	 (NULL_TREE, const_string_type_node, tree_cons
  	  (NULL_TREE, build_pointer_type (type_info_type_node),
  	   void_list_node)));
!       fn = push_void_library_fn (fn, tmp);
      }
  
!   fn = build_call (fn, elems);
    finish_expr_stmt (fn);
  }
  
*************** expand_class_desc (tdecl, type)
*** 1072,1090 ****
  	 (NULL_TREE, const_string_type_node, tree_cons
  	  (NULL_TREE, build_pointer_type (base_desc_type_node), tree_cons
  	   (NULL_TREE, sizetype, void_list_node))));
!       tmp = build_function_type	(void_type_node, tmp);
!   
!       fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
!       DECL_EXTERNAL (fn) = 1;
!       TREE_PUBLIC (fn) = 1;
!       DECL_ARTIFICIAL (fn) = 1;
!       TREE_NOTHROW (fn) = 1;
!       pushdecl_top_level (fn);
!       make_function_rtl (fn);
      }
  
!   mark_used (fn);
!   fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
    finish_expr_stmt (fn);
  }
  
--- 1016,1026 ----
  	 (NULL_TREE, const_string_type_node, tree_cons
  	  (NULL_TREE, build_pointer_type (base_desc_type_node), tree_cons
  	   (NULL_TREE, sizetype, void_list_node))));
! 
!       fn = push_void_library_fn (fn, tmp);
      }
  
!   fn = build_call (fn, elems);
    finish_expr_stmt (fn);
  }
  
*************** expand_ptr_desc (tdecl, type)
*** 1117,1135 ****
  	 (NULL_TREE, const_string_type_node, tree_cons
  	  (NULL_TREE, build_pointer_type (type_info_type_node),
  	   void_list_node)));
!       tmp = build_function_type	(void_type_node, tmp);
!   
!       fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
!       DECL_EXTERNAL (fn) = 1;
!       TREE_PUBLIC (fn) = 1;
!       DECL_ARTIFICIAL (fn) = 1;
!       TREE_NOTHROW (fn) = 1;
!       pushdecl_top_level (fn);
!       make_function_rtl (fn);
      }
  
!   mark_used (fn);
!   fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
    finish_expr_stmt (fn);
  }
  
--- 1053,1062 ----
  	 (NULL_TREE, const_string_type_node, tree_cons
  	  (NULL_TREE, build_pointer_type (type_info_type_node),
  	   void_list_node)));
!       fn = push_void_library_fn (fn, tmp);
      }
  
!   fn = build_call (fn, elems);
    finish_expr_stmt (fn);
  }
  
*************** expand_attr_desc (tdecl, type)
*** 1163,1181 ****
  	  (NULL_TREE, integer_type_node, tree_cons
  	   (NULL_TREE, build_pointer_type (type_info_type_node),
  	    void_list_node))));
!       tmp = build_function_type	(void_type_node, tmp);
!   
!       fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
!       DECL_EXTERNAL (fn) = 1;
!       TREE_PUBLIC (fn) = 1;
!       DECL_ARTIFICIAL (fn) = 1;
!       TREE_NOTHROW (fn) = 1;
!       pushdecl_top_level (fn);
!       make_function_rtl (fn);
      }
  
!   mark_used (fn);
!   fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
    finish_expr_stmt (fn);
  }
  
--- 1090,1099 ----
  	  (NULL_TREE, integer_type_node, tree_cons
  	   (NULL_TREE, build_pointer_type (type_info_type_node),
  	    void_list_node))));
!       fn = push_void_library_fn (fn, tmp);
      }
  
!   fn = build_call (fn, elems);
    finish_expr_stmt (fn);
  }
  
*************** expand_generic_desc (tdecl, type, fnname
*** 1201,1219 ****
        tmp = tree_cons
  	(NULL_TREE, ptr_type_node, tree_cons
  	 (NULL_TREE, const_string_type_node, void_list_node));
!       tmp = build_function_type (void_type_node, tmp);
!   
!       fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
!       DECL_EXTERNAL (fn) = 1;
!       TREE_PUBLIC (fn) = 1;
!       DECL_ARTIFICIAL (fn) = 1;
!       TREE_NOTHROW (fn) = 1;
!       pushdecl_top_level (fn);
!       make_function_rtl (fn);
      }
  
!   mark_used (fn);
!   fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
    finish_expr_stmt (fn);
  }
  
--- 1119,1128 ----
        tmp = tree_cons
  	(NULL_TREE, ptr_type_node, tree_cons
  	 (NULL_TREE, const_string_type_node, void_list_node));
!       fn = push_void_library_fn (fn, tmp);
      }
  
!   fn = build_call (fn, elems);
    finish_expr_stmt (fn);
  }
  
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.261
diff -c -p -r1.261 typeck.c
*** typeck.c	2000/03/08 11:21:28	1.261
--- typeck.c	2000/03/10 09:16:53
*************** build_function_call_real (function, para
*** 3046,3053 ****
      }
  
    /* C++ */
!   value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node;
!   result = build_call (function, value_type, coerced_params);
  
    if (require_complete)
      {
--- 3046,3053 ----
      }
  
    /* C++ */
!   result = build_call (function, coerced_params);
!   value_type = TREE_TYPE (result);
  
    if (require_complete)
      {

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