OSDN Git Service

tweak formatting
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 63fc93a..20a6aba 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));
@@ -1789,9 +1789,12 @@ wrapup_globals_for_namespace (namespace, data)
       /* Pretend we've output an unused static variable.  This ensures
          that the toplevel __FUNCTION__ etc won't be emitted, unless
          needed. */
-      if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
-          && !TREE_USED (decl))
-        TREE_ASM_WRITTEN (decl) = 1;
+      if (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)
+         && !TREE_PUBLIC (decl) && !TREE_USED (decl))
+       {
+         TREE_ASM_WRITTEN (decl) = 1;
+         DECL_IGNORED_P (decl) = 1;
+       }
       vec[len - i - 1] = decl;
     }
 
@@ -5937,26 +5940,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.
@@ -6143,7 +6126,8 @@ init_decl_processing ()
   boolean_true_node = build_int_2 (1, 0);
   TREE_TYPE (boolean_true_node) = boolean_type_node;
 
-  signed_size_zero_node = build_int_2 (0, 0);  record_builtin_type (RID_FLOAT, NULL_PTR, float_type_node);
+  signed_size_zero_node = build_int_2 (0, 0);
+  record_builtin_type (RID_FLOAT, NULL_PTR, float_type_node);
   record_builtin_type (RID_DOUBLE, NULL_PTR, double_type_node);
   record_builtin_type (RID_MAX, "long double", long_double_type_node);
 
@@ -6320,15 +6304,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,56 +6445,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;
+  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.  */
 
-/* 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.  */
+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
-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_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, type)
+     tree name, type;
+{
+  tree fn = push_library_fn (name, type);
+  TREE_THIS_VOLATILE (fn) = 1;
+  TREE_NOTHROW (fn) = 0;
+  return fn;
 }
 \f
 /* When we call finish_struct for an anonymous union, we create
@@ -7194,7 +7276,7 @@ maybe_commonize_var (decl)
      linkage.  */
   if (TREE_STATIC (decl)
       /* Don't mess with __FUNCTION__.  */
-      && ! TREE_ASM_WRITTEN (decl)
+      && ! DECL_ARTIFICIAL (decl)
       && current_function_decl
       && DECL_CONTEXT (decl) == current_function_decl
       && (DECL_THIS_INLINE (current_function_decl)
@@ -7229,7 +7311,7 @@ maybe_commonize_var (decl)
          if (TREE_PUBLIC (decl))
            DECL_ASSEMBLER_NAME (decl)
              = build_static_name (current_function_decl, DECL_NAME (decl));
-         else if (! DECL_ARTIFICIAL (decl))
+         else
            {
              cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
              cp_warning_at ("  you can work around this by removing the initializer", decl);
@@ -7980,7 +8062,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);
@@ -8590,6 +8672,9 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
        tentative.  error_mark_node is replaced later with the BLOCK.  */
     DECL_INITIAL (decl) = error_mark_node;
 
+  if (nothrow_libfn_p (decl))
+    TREE_NOTHROW (decl) = 1;
+
   /* Caller will do the rest of this.  */
   if (check < 0)
     return decl;
@@ -11980,16 +12065,17 @@ grok_op_properties (decl, virtualp, friendp)
       if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl))
        {
          tree t = TREE_TYPE (name);
-         if (TREE_CODE (t) == VOID_TYPE)
-           pedwarn ("void is not a valid type conversion operator");
-         else if (! friendp)
+         if (! friendp)
            {
              int ref = (TREE_CODE (t) == REFERENCE_TYPE);
              const char *what = 0;
+             
              if (ref)
                t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
 
-             if (t == current_class_type)
+             if (TREE_CODE (t) == VOID_TYPE)
+               what = "void";
+             else if (t == current_class_type)
                what = "the same type";
              /* Don't force t to be complete here.  */
              else if (IS_AGGR_TYPE (t)
@@ -13484,6 +13570,7 @@ store_parm_decls ()
 
   /* Do the starting of the exception specifications, if we have any.  */
   if (flag_exceptions && !processing_template_decl
+      && flag_enforce_eh_specs
       && building_stmt_tree ()
       && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
     current_eh_spec_try_block = expand_start_eh_spec ();
@@ -13761,6 +13848,7 @@ finish_function (lineno, flags)
 
       /* Finish dealing with exception specifiers.  */
       if (flag_exceptions && !processing_template_decl
+         && flag_enforce_eh_specs
          && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
        expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS
                            (TREE_TYPE (current_function_decl)),