OSDN Git Service

* decl.c (decls_match): Allow a redeclaration of a builtin to
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index a6672b6..2760ea5 100644 (file)
@@ -336,10 +336,6 @@ extern int flag_no_builtin;
 
 extern int flag_no_nonansi_builtin;
 
-/* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
-   objects.  */
-extern int flag_huge_objects;
-
 /* Nonzero if we want to conserve space in the .o files.  We do this
    by putting uninitialized data and runtime initialized data into
    .common instead of .data at the expense of not flagging multiple
@@ -2940,7 +2936,8 @@ decls_match (newdecl, olddecl)
 
       if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
        {
-         if (! strict_prototypes_lang_c && DECL_LANGUAGE (olddecl) == lang_c
+         if ((! strict_prototypes_lang_c || DECL_BUILT_IN (olddecl))
+             && DECL_LANGUAGE (olddecl) == lang_c
              && p2 == NULL_TREE)
            {
              types_match = self_promoting_args_p (p1);
@@ -6045,6 +6042,8 @@ typedef struct predefined_identifier
   const char *name;
   /* The place where the IDENTIFIER_NODE should be stored.  */
   tree *node;
+  /* Non-zero if this is the name of a constructor or destructor.  */
+  int ctor_or_dtor_p;
 } predefined_identifier;
 
 /* Create all the predefined identifiers.  */
@@ -6056,29 +6055,35 @@ initialize_predefined_identifiers ()
 
   /* A table of identifiers to create at startup.  */
   static predefined_identifier predefined_identifiers[] = {
-    { "C++", &lang_name_cplusplus },
-    { "C", &lang_name_c },
-    { "Java", &lang_name_java },
-    { CTOR_NAME, &ctor_identifier },
-    { "__base_ctor", &base_ctor_identifier },
-    { "__comp_ctor", &complete_ctor_identifier },
-    { DTOR_NAME, &dtor_identifier },
-    { "__base_dtor", &base_dtor_identifier },
-    { "__deleting_dtor", &deleting_dtor_identifier },
-    { VTABLE_DELTA2_NAME, &delta2_identifier },
-    { VTABLE_DELTA_NAME, &delta_identifier },
-    { IN_CHARGE_NAME, &in_charge_identifier },
-    { VTABLE_INDEX_NAME, &index_identifier },
-    { "nelts", &nelts_identifier },
-    { THIS_NAME, &this_identifier },
-    { VTABLE_PFN_NAME, &pfn_identifier },
-    { "__pfn_or_delta2", &pfn_or_delta2_identifier },
-    { "_vptr", &vptr_identifier },
-    { NULL, NULL }
+    { "C++", &lang_name_cplusplus, 0 },
+    { "C", &lang_name_c, 0 },
+    { "Java", &lang_name_java, 0 },
+    { CTOR_NAME, &ctor_identifier, 1 },
+    { "__base_ctor", &base_ctor_identifier, 1 },
+    { "__comp_ctor", &complete_ctor_identifier, 1 },
+    { DTOR_NAME, &dtor_identifier, 1 },
+    { "__comp_dtor", &complete_dtor_identifier, 1 },
+    { "__base_dtor", &base_dtor_identifier, 1 },
+    { "__deleting_dtor", &deleting_dtor_identifier, 1 },
+    { VTABLE_DELTA2_NAME, &delta2_identifier, 0 },
+    { VTABLE_DELTA_NAME, &delta_identifier, 0 },
+    { IN_CHARGE_NAME, &in_charge_identifier, 0 },
+    { VTABLE_INDEX_NAME, &index_identifier, 0 },
+    { "nelts", &nelts_identifier, 0 },
+    { THIS_NAME, &this_identifier, 0 },
+    { VTABLE_PFN_NAME, &pfn_identifier, 0 },
+    { "__pfn_or_delta2", &pfn_or_delta2_identifier, 0 },
+    { "_vptr", &vptr_identifier, 0 },
+    { "__cp_push_exception", &cp_push_exception_identifier, 0 },
+    { NULL, NULL, 0 }
   };
 
   for (pid = predefined_identifiers; pid->name; ++pid)
-    *pid->node = get_identifier (pid->name);
+    {
+      *pid->node = get_identifier (pid->name);
+      if (pid->ctor_or_dtor_p)
+       IDENTIFIER_CTOR_OR_DTOR_P (*pid->node) = 1;
+    }
 }
 
 /* Create the predefined scalar types of C,
@@ -8283,7 +8288,7 @@ end_cleanup_fn ()
 {
   do_poplevel ();
 
-  expand_body (finish_function (lineno, 0));
+  expand_body (finish_function (0));
 
   pop_from_top_level ();
 }
@@ -11250,7 +11255,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)));
 
                /* Skip the `in_chrg' argument too, if present.  */
-               if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (decl)))
+               if (DECL_HAS_IN_CHARGE_PARM_P (decl))
                  arg_types = TREE_CHAIN (arg_types);
 
                if (arg_types == void_list_node
@@ -11968,8 +11973,7 @@ copy_args_p (d)
     return 0;
 
   t = FUNCTION_ARG_CHAIN (d);
-  if (DECL_CONSTRUCTOR_P (d)
-      && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (d)))
+  if (DECL_CONSTRUCTOR_P (d) && DECL_HAS_IN_CHARGE_PARM_P (d))
     t = TREE_CHAIN (t);
   if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
       && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
@@ -12000,7 +12004,7 @@ grok_ctor_properties (ctype, decl)
      added to any ctor so we can tell if the class has been initialized
      yet.  This could screw things up in this function, so we deliberately
      ignore the leading int if we're in that situation.  */
-  if (TYPE_USES_VIRTUAL_BASECLASSES (ctype))
+  if (DECL_HAS_IN_CHARGE_PARM_P (decl))
     {
       my_friendly_assert (parmtypes
                          && TREE_VALUE (parmtypes) == integer_type_node,
@@ -13444,8 +13448,7 @@ start_function (declspecs, declarator, attrs, flags)
 
       /* Constructors and destructors need to know whether they're "in
         charge" of initializing virtual base classes.  */
-      if (DECL_CONSTRUCTOR_FOR_VBASE_P (decl1)
-         || DECL_DESTRUCTOR_P (decl1))
+      if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
        current_in_charge_parm = TREE_CHAIN (t);
     }
 
@@ -13812,9 +13815,9 @@ static void
 finish_destructor_body ()
 {
   tree compound_stmt;
-  tree in_charge;
   tree virtual_size;
   tree exprstmt;
+  tree if_stmt;
 
   /* Create a block to contain all the extra code.  */
   compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
@@ -13832,16 +13835,9 @@ finish_destructor_body ()
      will set the flag again.  */
   TYPE_HAS_DESTRUCTOR (current_class_type) = 0;
 
-  /* These are two cases where we cannot delegate deletion.  */
-  if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)
-      || TYPE_GETS_REG_DELETE (current_class_type))
-    in_charge = integer_zero_node;
-  else
-    in_charge = current_in_charge_parm;
-
   exprstmt = build_delete (current_class_type,
                           current_class_ref,
-                          in_charge,
+                          integer_zero_node,
                           LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL,
                           0);
 
@@ -13874,8 +13870,8 @@ finish_destructor_body ()
                     TYPE_BINFO (current_class_type));
                  finish_expr_stmt
                    (build_scoped_method_call
-                    (current_class_ref, vb, dtor_identifier,
-                     build_tree_list (NULL_TREE, integer_zero_node)));
+                    (current_class_ref, vb, complete_dtor_identifier,
+                     NULL_TREE));
                }
              vbases = TREE_CHAIN (vbases);
            }
@@ -13898,24 +13894,18 @@ finish_destructor_body ()
      only defines placement deletes we don't do anything here.  So we
      pass LOOKUP_SPECULATIVELY; delete_sanity will complain for us if
      they ever try to delete one of these.  */
-  if (TYPE_GETS_REG_DELETE (current_class_type)
-      || TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
-    {
-      tree if_stmt;
-
-      exprstmt = build_op_delete_call
-       (DELETE_EXPR, current_class_ptr, virtual_size,
-        LOOKUP_NORMAL | LOOKUP_SPECULATIVELY, NULL_TREE);
-
-      if_stmt = begin_if_stmt ();
-      finish_if_stmt_cond (build (BIT_AND_EXPR, integer_type_node,
-                                 current_in_charge_parm,
-                                 integer_one_node),
-                          if_stmt);
-      finish_expr_stmt (exprstmt);
-      finish_then_clause (if_stmt);
-      finish_if_stmt ();
-    }
+  exprstmt = build_op_delete_call
+    (DELETE_EXPR, current_class_ptr, virtual_size,
+     LOOKUP_NORMAL | LOOKUP_SPECULATIVELY, NULL_TREE);
+
+  if_stmt = begin_if_stmt ();
+  finish_if_stmt_cond (build (BIT_AND_EXPR, integer_type_node,
+                             current_in_charge_parm,
+                             integer_one_node),
+                      if_stmt);
+  finish_expr_stmt (exprstmt);
+  finish_then_clause (if_stmt);
+  finish_if_stmt ();
 
   /* Close the block we started above.  */
   finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
@@ -13925,9 +13915,6 @@ finish_destructor_body ()
    all the way to assembler language output.  The free the storage
    for the function definition.
 
-   This is called after parsing the body of the function definition.
-   LINENO is the current line number.
-
    FLAGS is a bitwise or of the following values:
      1 - CALL_POPLEVEL
        An extra call to poplevel (and expand_end_bindings) must be
@@ -13939,8 +13926,7 @@ finish_destructor_body ()
        after the class definition is complete.)  */
 
 tree
-finish_function (lineno, flags)
-     int lineno;
+finish_function (flags)
      int flags;
 {
   register tree fndecl = current_function_decl;
@@ -13951,6 +13937,7 @@ finish_function (lineno, flags)
   int inclass_inline = (flags & 2) != 0;
   int expand_p;
   int nested;
+  int current_line = lineno;
 
   /* When we get some parse errors, we can end up without a
      current_function_decl, so cope.  */
@@ -13971,7 +13958,11 @@ finish_function (lineno, flags)
       store_parm_decls ();
     }
 
-  if (building_stmt_tree ())
+  /* For a cloned function, we've already got all the code we need;
+     there's no need to add any extra bits.  */
+  if (building_stmt_tree () && DECL_CLONED_FUNCTION_P (fndecl))
+    ;
+  else if (building_stmt_tree ())
     {
       if (DECL_CONSTRUCTOR_P (fndecl))
        {
@@ -14065,7 +14056,7 @@ finish_function (lineno, flags)
          DECL_CONTEXT (no_return_label) = fndecl;
          DECL_INITIAL (no_return_label) = error_mark_node;
          DECL_SOURCE_FILE (no_return_label) = input_filename;
-         DECL_SOURCE_LINE (no_return_label) = lineno;
+         DECL_SOURCE_LINE (no_return_label) = current_line;
          expand_goto (no_return_label);
        }
 
@@ -14104,7 +14095,7 @@ finish_function (lineno, flags)
       immediate_size_expand = 1;
 
       /* Generate rtl for function exit.  */
-      expand_function_end (input_filename, lineno, 1);
+      expand_function_end (input_filename, current_line, 1);
     }
 
   /* We have to save this value here in case
@@ -14560,16 +14551,6 @@ maybe_build_cleanup_1 (decl, auto_delete)
 }
 
 /* If DECL is of a type which needs a cleanup, build that cleanup
-   here.  The cleanup does free the storage with a call to delete.  */
-
-tree
-maybe_build_cleanup_and_delete (decl)
-     tree decl;
-{
-  return maybe_build_cleanup_1 (decl, integer_three_node);
-}
-
-/* If DECL is of a type which needs a cleanup, build that cleanup
    here.  The cleanup does not free the storage with a call a delete.  */
 
 tree
@@ -14768,6 +14749,7 @@ lang_mark_tree (t)
            {
              ggc_mark_tree (ld->befriending_classes);
              ggc_mark_tree (ld->saved_tree);
+             ggc_mark_tree (ld->cloned_function);
              if (TREE_CODE (t) == TYPE_DECL)
                ggc_mark_tree (ld->u.sorted_fields);
              else if (TREE_CODE (t) == FUNCTION_DECL