OSDN Git Service

* decl.c (push_overloaded_decl_1, auto_function,
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Mar 2000 09:25:45 +0000 (09:25 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Mar 2000 09:25:45 +0000 (09:25 +0000)
        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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32468 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/rtti.c
gcc/cp/typeck.c

index 27b823e..e549057 100644 (file)
@@ -1,3 +1,27 @@
+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.
+
 2000-03-09  Jason Merrill  <jason@casey.cygnus.com>
 
        * call.c (build_call): Set TREE_NOTHROW on the CALL_EXPR as
index e15d4f0..40cd43d 100644 (file)
@@ -364,13 +364,14 @@ build_addr_func (function)
    (TYPE_PTRMEMFUNC_P) must be handled by our callers.  */
 
 tree
-build_call (function, result_type, parms)
-     tree function, result_type, parms;
+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);
 
@@ -380,6 +381,8 @@ build_call (function, result_type, parms)
       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);
@@ -394,8 +397,14 @@ build_call (function, result_type, parms)
   if (decl && DECL_CONSTRUCTOR_P (decl))
     is_constructor = 1;
 
-  if (decl)
-    my_friendly_assert (TREE_USED (decl), 990125);
+  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.
@@ -4157,7 +4166,7 @@ build_over_call (cand, args, flags)
        return exp;
     }
 
-  fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args);
+  fn = build_call (fn, converted_args);
   if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE)
     return fn;
   fn = require_complete_type (fn);
index 9086292..f7baceb 100644 (file)
@@ -577,8 +577,6 @@ enum cp_tree_index
     CPTI_TERMINATE,
     CPTI_ATEXIT,
     CPTI_DSO_HANDLE,
-    CPTI_BAD_CAST,
-    CPTI_BAD_TYPEID,
     CPTI_DCAST,
 
     CPTI_MAX
@@ -686,12 +684,6 @@ extern tree cp_global_trees[CPTI_MAX];
 /* 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]
 
@@ -3605,7 +3597,7 @@ extern tree build_vfield_ref                      PARAMS ((tree, tree));
 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_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));
@@ -3753,12 +3745,16 @@ extern tree namespace_ancestor                  PARAMS ((tree, tree));
 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 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 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));
index b16d9d8..7133190 100644 (file)
@@ -113,7 +113,6 @@ static void declare_namespace_level PARAMS ((void));
 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));
@@ -133,6 +132,7 @@ static void set_identifier_type_value_with_scope
        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));
@@ -5937,26 +5937,6 @@ record_unknown_type (type, name)
   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.
@@ -6320,15 +6300,15 @@ init_decl_processing ()
     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);
+    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
-    = define_function ("__pure_virtual", void_ftype, 0, 0);
+    = build_library_fn_ptr ("__pure_virtual", void_ftype);
 
   /* Perform other language dependent initializations.  */
   init_class_processing ();
@@ -6461,60 +6441,154 @@ lang_print_error_function (file)
   maybe_print_template_context ();
 }
 
-/* Make a definition for a builtin function named NAME and whose data type
+/* 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.
 
-   If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
+   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
-define_function (name, type, pfn, library_name)
+builtin_function (name, type, code, class, libname)
      const char *name;
      tree type;
-     void (*pfn) PARAMS ((tree));
-     const char *library_name;
+     int code;
+     enum built_in_class class;
+     const char *libname;
 {
-  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;
+  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);
-  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);
+  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;
+}
 
-/* 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.  */
+/* 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
-builtin_function (name, type, code, class, libname)
+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;
-     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;
+  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;
 }
 \f
 /* When we call finish_struct for an anonymous union, we create
@@ -7984,7 +8058,7 @@ get_atexit_node ()
 
   /* Now, build the function declaration.  */
   push_lang_context (lang_name_c);
-  atexit_fndecl = define_function (name, fn_type, /*pfn=*/0, NULL_PTR);
+  atexit_fndecl = build_library_fn_ptr (name, fn_type);
   mark_used (atexit_fndecl);
   pop_lang_context ();
   atexit_node = default_conversion (atexit_fndecl);
index b8d4fa2..ae64e78 100644 (file)
@@ -173,8 +173,9 @@ init_exception_processing ()
   
   if (flag_honor_std)
     push_namespace (get_identifier ("std"));
-  terminate_node = auto_function (get_identifier ("terminate"), vtype);
+  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 ();
 
@@ -253,16 +254,8 @@ call_eh_info ()
       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);
+      fn = push_library_fn (fn, build_function_type (t, void_list_node));
     }
-  mark_used (fn);
   return build_function_call (fn, NULL_TREE);
 }
 
@@ -424,18 +417,12 @@ do_pop_exception ()
     {
       /* 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);
+      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;
     }
 
-  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
@@ -732,21 +719,13 @@ expand_end_eh_spec (raises, try_block)
       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);
+
+      fn = push_throw_library_fn (fn, tmp);
     }
 
-  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);
+  tmp = build_call (fn, tmp);
   finish_expr_stmt (tmp);
 
   finish_handler (blocks, handler);
@@ -799,19 +778,10 @@ alloc_eh_object (type)
   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);
+      tree tmp = tree_cons (NULL_TREE, sizetype, void_list_node);
+      fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
     }
 
-  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);
@@ -852,16 +822,11 @@ expand_throw (exp)
        {
          /* 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 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;
-         pushdecl_top_level (fn);
-         make_function_rtl (fn);
+         TREE_NOTHROW (fn) = 0;
        }
 
       exp = build_function_call (fn, args);
@@ -974,17 +939,9 @@ expand_throw (exp)
            (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);
+         fn = push_void_library_fn (fn, tmp);
        }
 
-      mark_used (fn);
       e = tree_cons (NULL_TREE, exp, tree_cons
                     (NULL_TREE, throw_type, tree_cons
                      (NULL_TREE, cleanup, NULL_TREE)));
@@ -1000,21 +957,10 @@ expand_throw (exp)
       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);
-       }
+       /* Declare void __uncatch_exception (void)
+          as defined in exception.cc. */
+       fn = push_void_library_fn (fn, void_list_node);
 
-      mark_used (fn);
       exp = build_function_call (fn, NULL_TREE);
     }
 
index a2e0d22..e448218 100644 (file)
@@ -1868,8 +1868,7 @@ build_builtin_delete_call (addr)
      tree addr;
 {
   mark_used (global_delete_fndecl);
-  return build_call (global_delete_fndecl, 
-                    void_type_node, build_tree_list (NULL_TREE, addr));
+  return build_call (global_delete_fndecl, build_tree_list (NULL_TREE, addr));
 }
 \f
 /* Generate a C++ "new" expression. DECL is either a TREE_LIST
index 6e869f1..38e9c58 100644 (file)
@@ -2156,7 +2156,7 @@ emit_thunk (thunk_fndecl)
     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);
+    t = build_call (function, t);
     finish_return_stmt (t);
 
     expand_body (finish_function (lineno, 0));
index f29da8c..15e4617 100644 (file)
@@ -45,7 +45,6 @@ Boston, MA 02111-1307, USA.  */
 
 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));
@@ -165,35 +164,6 @@ build_headof (exp)
                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 */
@@ -201,28 +171,27 @@ build_runtime_decl (name, type)
 static tree
 throw_bad_cast ()
 {
-  if (!throw_bad_cast_node)
-    throw_bad_cast_node = build_runtime_decl
-        ("__throw_bad_cast", ptr_type_node);
+  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 (throw_bad_cast_node,
-                     TREE_TYPE (TREE_TYPE (throw_bad_cast_node)),
-                     NULL_TREE);
+  return build_call (fn, 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)));
+  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 (throw_bad_typeid_node,
-                     TREE_TYPE (TREE_TYPE (throw_bad_typeid_node)),
-                     NULL_TREE);
+  return build_call (fn, NULL_TREE);
 }
 \f
 /* Return a pointer to type_info function associated with the expression EXP.
@@ -420,17 +389,10 @@ get_tinfo_decl (type)
     {
       /* 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;
+      d = push_library_fn (name, tinfo_decl_type);
       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
@@ -468,7 +430,7 @@ tinfo_from_decl (expr)
   tree t;
   
   if (!new_abi_rtti_p ())
-    t = build_call (expr, TREE_TYPE (tinfo_decl_type), NULL_TREE);
+    t = build_call (expr, NULL_TREE);
   else if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
     t = build_indirect_ref (expr, NULL);
   else
@@ -814,24 +776,15 @@ build_dynamic_cast_1 (type, expr)
                          (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);
+               /* 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;
            }
-         mark_used (dcast_fn);
-          result = build_call
-           (dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
+          result = build_call (dcast_fn, elems);
 
          if (tc == REFERENCE_TYPE)
            {
@@ -912,19 +865,10 @@ expand_si_desc (tdecl, type)
         (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);
+      fn = push_void_library_fn (fn, tmp);
     }
 
-  mark_used (fn);
-  fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
+  fn = build_call (fn, elems);
   finish_expr_stmt (fn);
 }
 
@@ -1072,19 +1016,11 @@ expand_class_desc (tdecl, type)
         (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);
+
+      fn = push_void_library_fn (fn, tmp);
     }
 
-  mark_used (fn);
-  fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
+  fn = build_call (fn, elems);
   finish_expr_stmt (fn);
 }
 
@@ -1117,19 +1053,10 @@ expand_ptr_desc (tdecl, type)
         (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);
+      fn = push_void_library_fn (fn, tmp);
     }
 
-  mark_used (fn);
-  fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
+  fn = build_call (fn, elems);
   finish_expr_stmt (fn);
 }
 
@@ -1163,19 +1090,10 @@ expand_attr_desc (tdecl, type)
          (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);
+      fn = push_void_library_fn (fn, tmp);
     }
 
-  mark_used (fn);
-  fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
+  fn = build_call (fn, elems);
   finish_expr_stmt (fn);
 }
 
@@ -1201,19 +1119,10 @@ expand_generic_desc (tdecl, type, fnname)
       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);
+      fn = push_void_library_fn (fn, tmp);
     }
 
-  mark_used (fn);
-  fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
+  fn = build_call (fn, elems);
   finish_expr_stmt (fn);
 }
 
index 868ebec..aed8bb3 100644 (file)
@@ -3046,8 +3046,8 @@ build_function_call_real (function, params, require_complete, flags)
     }
 
   /* C++ */
-  value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node;
-  result = build_call (function, value_type, coerced_params);
+  result = build_call (function, coerced_params);
+  value_type = TREE_TYPE (result);
 
   if (require_complete)
     {