target-def.h (TARGET_CXX_CDTOR_RETURNS_THIS): Define.
authorPaul Brook <paul@codesourcery.com>
Wed, 4 Aug 2004 15:33:51 +0000 (15:33 +0000)
committerPaul Brook <pbrook@gcc.gnu.org>
Wed, 4 Aug 2004 15:33:51 +0000 (15:33 +0000)
gcc/
* target-def.h (TARGET_CXX_CDTOR_RETURNS_THIS): Define.
(TARGET_CXX): Use it.
* target.h (struct gcc_target): Add cdtor_returns_this.
* config/arm/arm.c (arm_cxx_cdtor_returns_this): New function.
(TARGET_CXX_CDTOR_RETURNS_THIS): Define.
* doc/tm.texi: Document TARGET_CXX_CDTOR_RETURNS_THIS.
gcc/cp/
* Make-lang.in (cp/semantics.o, cp/optimize.o): Depend on TARGET_H.
* cp-tree.h (struct language_function): Rename x_dtor_label to
x_cdtor_label.
(dtor_label): Rename ...
(cdtor_label): ... to this.
* decl.c (begin_constructor_body): Remove.
(check_special_function_return_type): Maybe change the return type.
(grokdeclarator): Pass the class type.
(start_preparsed_function): Constructors may need a return label.
(finish_constructor_body, finish_destructor_body): Set the return
value.
(begin_function_body): Don't call begin_constructor_body.
(finish_function): Don't warn for constructors or destructors.
(implicitly_declare_fn): Maybe change the return type.
* optimize.c: Include target.h.
(maybe_clone_body): Remap the function result.
* semantics.c: Include target.h.
(finish_return_stmt): Maybe jump to return label for constructors.

From-SVN: r85561

12 files changed:
gcc/ChangeLog
gcc/config/arm/arm.c
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/method.c
gcc/cp/optimize.c
gcc/cp/semantics.c
gcc/doc/tm.texi
gcc/target-def.h
gcc/target.h

index 81b43147a3662d1fe146c1ccf29a6016af1aa3ef..64fff1d6140e381c20e3b01fa6a2345f4f0cfd24 100644 (file)
@@ -1,3 +1,12 @@
+2004-08-04  Paul Brook  <paul@codesourcery.com>
+
+       * target-def.h (TARGET_CXX_CDTOR_RETURNS_THIS): Define.
+       (TARGET_CXX): Use it.
+       * target.h (struct gcc_target): Add cdtor_returns_this.
+       * config/arm/arm.c (arm_cxx_cdtor_returns_this): New function.
+       (TARGET_CXX_CDTOR_RETURNS_THIS): Define.
+       * doc/tm.texi: Document TARGET_CXX_CDTOR_RETURNS_THIS.
+
 2004-08-03  Nathan Sidwell  <nathan@codesourcery.com>
 
        * c-lex.c (narrowest_unsigned_type, narrowest_signed_type): Take
index 66fc8f88735de37896f8453dea3af7134d4f3b1f..8b1ae87f757eefb49b17b2d85cf52eb8a61cecd6 100644 (file)
@@ -168,6 +168,7 @@ static tree arm_cxx_guard_type (void);
 static bool arm_cxx_guard_mask_bit (void);
 static tree arm_get_cookie_size (tree);
 static bool arm_cookie_has_size (void);
+static bool arm_cxx_cdtor_returns_this (void);
 
 \f
 /* Initialize the GCC target structure.  */
@@ -282,6 +283,9 @@ static bool arm_cookie_has_size (void);
 #undef TARGET_CXX_COOKIE_HAS_SIZE
 #define TARGET_CXX_COOKIE_HAS_SIZE arm_cookie_has_size
 
+#undef TARGET_CXX_CDTOR_RETURNS_THIS
+#define TARGET_CXX_CDTOR_RETURNS_THIS arm_cxx_cdtor_returns_this
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Obstack for minipool constant handling.  */
@@ -14578,3 +14582,13 @@ arm_cookie_has_size (void)
 {
   return TARGET_AAPCS_BASED;
 }
+
+
+/* The EABI says constructors and destructors should return a pointer to
+   the object constructed/destroyed.  */
+
+static bool
+arm_cxx_cdtor_returns_this (void)
+{
+  return TARGET_AAPCS_BASED;
+}
index e82e5005d00b78885d31146115e61fc6b2148298..81ac439762718128a8e34a094d0ab40d9ad86eb0 100644 (file)
@@ -1,3 +1,24 @@
+2004-08-04  Paul Brook  <paul@codesourcery.com>
+
+       * Make-lang.in (cp/semantics.o, cp/optimize.o): Depend on TARGET_H.
+       * cp-tree.h (struct language_function): Rename x_dtor_label to
+       x_cdtor_label.
+       (dtor_label): Rename ...
+       (cdtor_label): ... to this.
+       * decl.c (begin_constructor_body): Remove.
+       (check_special_function_return_type): Maybe change the return type.
+       (grokdeclarator): Pass the class type.
+       (start_preparsed_function): Constructors may need a return label.
+       (finish_constructor_body, finish_destructor_body): Set the return
+       value.
+       (begin_function_body): Don't call begin_constructor_body.
+       (finish_function): Don't warn for constructors or destructors.
+       (implicitly_declare_fn): Maybe change the return type.
+       * optimize.c: Include target.h.
+       (maybe_clone_body): Remap the function result.
+       * semantics.c: Include target.h.
+       (finish_return_stmt): Maybe jump to return label for constructors.
+
 2004-08-03  Mark Mitchell  <mark@codesourcery.com>
 
        * class.c (build_vtable): Do not set DECL_VISIBILITY here.
index 1ce05dac03c95f5a60e3a70e235a05ef811e09d7..52337392d0b45454ed4ae34e7f59aef4d412b200 100644 (file)
@@ -260,10 +260,10 @@ cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h diagnostic.h \
   gt-cp-repo.h
 cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) except.h toplev.h \
   flags.h debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \
-  tree-inline.h cgraph.h
+  tree-inline.h cgraph.h $(TAREGT_H)
 cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) tree-dump.h
 cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h integrate.h insn-config.h \
-  input.h $(PARAMS_H) debug.h tree-inline.h tree-gimple.h
+  input.h $(PARAMS_H) debug.h tree-inline.h tree-gimple.h $(TARGET_H)
 cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h \
   $(TARGET_H) $(TM_P_H)
 
index 5b4992562386f34db78e7e4c3f8a824c68c6f0a0..e2c94f25ed27d7cc17aec0841c307afed0d5d166 100644 (file)
@@ -708,7 +708,7 @@ struct language_function GTY(())
 {
   struct c_language_function base;
 
-  tree x_dtor_label;
+  tree x_cdtor_label;
   tree x_current_class_ptr;
   tree x_current_class_ref;
   tree x_eh_spec_block;
@@ -735,10 +735,12 @@ struct language_function GTY(())
 
 #define cp_function_chain (cfun->language)
 
-/* In a destructor, the point at which all derived class destroying
-   has been done, just before any base class destroying will be done.  */
+/* In a constructor destructor, the point at which all derived class
+   destroying/contruction has been has been done. Ie. just before a
+   constuctor returns, or before any base class destroying will be done
+   in a destructor.  */
 
-#define dtor_label cp_function_chain->x_dtor_label
+#define cdtor_label cp_function_chain->x_cdtor_label
 
 /* When we're processing a member function, current_class_ptr is the
    PARM_DECL for the `this' pointer.  The current_class_ref is an
index 8c85e71003d24cb5298674f382d761aca2f84804..0f489976a637ba8cf40555b4de460b257fcac60e 100644 (file)
@@ -100,7 +100,6 @@ static tree check_initializer (tree, tree, int, tree *);
 static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
 static void save_function_data (tree);
 static void check_function_type (tree, tree);
-static void begin_constructor_body (void);
 static void finish_constructor_body (void);
 static void begin_destructor_body (void);
 static void finish_destructor_body (void);
@@ -6182,7 +6181,8 @@ create_array_type_for_decl (tree name, tree type, tree size)
 /* Check that it's OK to declare a function with the indicated TYPE.
    SFK indicates the kind of special function (if any) that this
    function is.  OPTYPE is the type given in a conversion operator
-   declaration.  Returns the actual return type of the function; that
+   declaration, or the class type for a constructor/destructor.
+   Returns the actual return type of the function; that
    may be different than TYPE if an error occurs, or for certain
    special functions.  */
 
@@ -6197,13 +6197,23 @@ check_special_function_return_type (special_function_kind sfk,
       if (type)
        error ("return type specification for constructor invalid");
 
-      type = void_type_node;
+      if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (optype))
+       type = build_pointer_type (optype);
+      else
+       type = void_type_node;
       break;
 
     case sfk_destructor:
       if (type)
        error ("return type specification for destructor invalid");
-      type = void_type_node;
+      /* We can't use the proper return type here because we run into
+        problems with abiguous bases and covariant returns.
+        Java classes are left unchanged because (void *) isn't a valid
+        Java type, and we don't want to change the Java ABI.  */
+      if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (optype))
+       type = build_pointer_type (void_type_node);
+      else
+       type = void_type_node;
       break;
 
     case sfk_conversion:
@@ -6589,6 +6599,9 @@ grokdeclarator (const cp_declarator *declarator,
   typedef_type = type;
 
 
+  if (sfk != sfk_conversion)
+    ctor_return_type = ctype;
+
   if (sfk != sfk_none)
     type = check_special_function_return_type (sfk, type,
                                               ctor_return_type);
@@ -9879,10 +9892,12 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
   ++function_depth;
 
-  if (DECL_DESTRUCTOR_P (decl1))
+  if (DECL_DESTRUCTOR_P (decl1)
+      || (DECL_CONSTRUCTOR_P (decl1)
+         && targetm.cxx.cdtor_returns_this ()))
     {
-      dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
-      DECL_CONTEXT (dtor_label) = current_function_decl;
+      cdtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+      DECL_CONTEXT (cdtor_label) = current_function_decl;
     }
 
   start_fname_decls ();
@@ -10050,22 +10065,27 @@ save_function_data (tree decl)
   f->x_local_names = NULL;
 }
 
-/* Add a note to mark the beginning of the main body of the constructor.
-   This is used to set up the data structures for the cleanup regions for
-   fully-constructed bases and members.  */
 
-static void
-begin_constructor_body (void)
-{
-}
-
-/* Add a note to mark the end of the main body of the constructor.  This is
-   used to end the cleanup regions for fully-constructed bases and
-   members.  */
+/* Set the return value of the constructor (if present).  */
 
 static void
 finish_constructor_body (void)
 {
+  tree val;
+  tree exprstmt;
+
+  if (targetm.cxx.cdtor_returns_this ())
+    {
+      /* Any return from a constructor will end up here.  */
+      add_stmt (build_stmt (LABEL_EXPR, cdtor_label));
+
+      val = DECL_ARGUMENTS (current_function_decl);
+      val = build (MODIFY_EXPR, TREE_TYPE (val),
+                  DECL_RESULT (current_function_decl), val);
+      /* Return the address of the object.  */
+      exprstmt = build_stmt (RETURN_EXPR, val);
+      add_stmt (exprstmt);
+    }
 }
 
 /* Do all the processing for the beginning of a destructor; set up the
@@ -10125,7 +10145,7 @@ finish_destructor_body (void)
 
   /* Any return from a destructor will end up here; that way all base
      and member cleanups will be run when the function returns.  */
-  add_stmt (build_stmt (LABEL_EXPR, dtor_label));
+  add_stmt (build_stmt (LABEL_EXPR, cdtor_label));
 
   /* In a virtual destructor, we must call delete.  */
   if (DECL_VIRTUAL_P (current_function_decl))
@@ -10152,6 +10172,18 @@ finish_destructor_body (void)
       finish_then_clause (if_stmt);
       finish_if_stmt (if_stmt);
     }
+
+  if (targetm.cxx.cdtor_returns_this ())
+    {
+      tree val;
+
+      val = DECL_ARGUMENTS (current_function_decl);
+      val = build (MODIFY_EXPR, TREE_TYPE (val),
+                  DECL_RESULT (current_function_decl), val);
+      /* Return the address of the object.  */
+      exprstmt = build_stmt (RETURN_EXPR, val);
+      add_stmt (exprstmt);
+    }
 }
 
 /* Do the necessary processing for the beginning of a function body, which
@@ -10177,8 +10209,6 @@ begin_function_body (void)
 
   if (processing_template_decl)
     /* Do nothing now.  */;
-  else if (DECL_CONSTRUCTOR_P (current_function_decl))
-    begin_constructor_body ();
   else if (DECL_DESTRUCTOR_P (current_function_decl))
     begin_destructor_body ();
 
@@ -10363,7 +10393,10 @@ finish_function (int flags)
       && !DECL_NAME (DECL_RESULT (fndecl))
       /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
         inline function, as we might never be compiled separately.  */
-      && (DECL_INLINE (fndecl) || processing_template_decl))
+      && (DECL_INLINE (fndecl) || processing_template_decl)
+      /* Structor return values (if any) are set by the compiler.  */
+      && !DECL_CONSTRUCTOR_P (fndecl)
+      && !DECL_DESTRUCTOR_P (fndecl))
     warning ("no return statement in function returning non-void");
 
   /* Store the end of the function, so that we get good line number
index 7a2a7624fd809d6616d6230d4229f38b9c213dac..317790e877f1c0f41890bdaefbd3190f6b1b34cc 100644 (file)
@@ -929,7 +929,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
 {
   tree fn;
   tree parameter_types = void_list_node;
-  tree return_type = void_type_node;
+  tree return_type;
   tree fn_type;
   tree raises = empty_except_spec;
   tree rhs_parm_type = NULL_TREE;
@@ -937,6 +937,17 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
 
   type = TYPE_MAIN_VARIANT (type);
 
+  if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (type))
+    {
+      if (kind == sfk_destructor)
+       /* See comment in check_special_function_return_type.  */
+       return_type = build_pointer_type (void_type_node);
+      else
+       return_type = build_pointer_type (type);
+    }
+  else
+    return_type = void_type_node;
+
   switch (kind)
     {
     case sfk_destructor:
index b94270eabd65cfe30ad8f4813912290276553fa3..7ccfaffbf0db38ab8ed0a1e73e422bc3207f39a8 100644 (file)
@@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "varray.h"
 #include "params.h"
 #include "hashtab.h"
+#include "target.h"
 #include "debug.h"
 #include "tree-inline.h"
 #include "flags.h"
@@ -184,6 +185,13 @@ maybe_clone_body (tree fn)
            }
        }
 
+      if (targetm.cxx.cdtor_returns_this ())
+       {
+         parm = DECL_RESULT (fn);
+         clone_parm = DECL_RESULT (clone);
+         splay_tree_insert (decl_map, (splay_tree_key) parm,
+                            (splay_tree_value) clone_parm);
+       }
       /* Clone the body.  */
       clone_body (clone, fn, decl_map);
 
index 606fe5fc3f64793808e813c70b3cbbaa640a4c8e..cf61c221e7284c271a9beb66c0e3abc3db3edea6 100644 (file)
@@ -45,6 +45,7 @@
 #include "cgraph.h"
 #include "tree-iterator.h"
 #include "vec.h"
+#include "target.h"
 
 /* There routines provide a modular interface to perform many parsing
    operations.  They may therefore be used during actual parsing, or
@@ -703,13 +704,15 @@ finish_return_stmt (tree expr)
   expr = check_return_expr (expr);
   if (!processing_template_decl)
     {
-      if (DECL_DESTRUCTOR_P (current_function_decl))
+      if (DECL_DESTRUCTOR_P (current_function_decl)
+         || (DECL_CONSTRUCTOR_P (current_function_decl) 
+             && targetm.cxx.cdtor_returns_this ()))
        {
          /* Similarly, all destructors must run destructors for
             base-classes before returning.  So, all returns in a
             destructor get sent to the DTOR_LABEL; finish_function emits
             code to return a value there.  */
-         return finish_goto_stmt (dtor_label);
+         return finish_goto_stmt (cdtor_label);
        }
     }
 
index 76fd3871f19e19bfbd6768aea09327de1c98a69b..cc3cfeebee420c97465704f61804e3318289fa66 100644 (file)
@@ -8469,6 +8469,12 @@ modified value and perform any other actions necessary to support the
 backend's targeted operating system.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_CXX_CDTOR_RETURNS_THIS (void)
+This hook should return @code{true} if constructors and destructors return
+the address of the object created/destroyed.  The default is to return
+@code{false}.
+@end deftypefn
+
 @node Misc
 @section Miscellaneous Parameters
 @cindex parameters, miscellaneous
index a3edb019a14836037414a67b157ca4f336416a6d..fe06c8c702a7f6f4a4fa3995880f9fa23bf06247 100644 (file)
@@ -412,13 +412,18 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #define TARGET_CXX_IMPORT_EXPORT_CLASS NULL
 #endif
 
+#ifndef TARGET_CXX_CDTOR_RETURNS_THIS
+#define TARGET_CXX_CDTOR_RETURNS_THIS hook_bool_void_false
+#endif
+
 #define TARGET_CXX             \
   {                            \
     TARGET_CXX_GUARD_TYPE,     \
     TARGET_CXX_GUARD_MASK_BIT, \
     TARGET_CXX_GET_COOKIE_SIZE,        \
     TARGET_CXX_COOKIE_HAS_SIZE,        \
-    TARGET_CXX_IMPORT_EXPORT_CLASS     \
+    TARGET_CXX_IMPORT_EXPORT_CLASS,    \
+    TARGET_CXX_CDTOR_RETURNS_THIS      \
   }
 
 /* The whole shebang.  */
index cdcaa18acd9826d4cf02562038e1a68c5276e887..44562da3964d0d7a4987e79b49b83b610146da52 100644 (file)
@@ -492,6 +492,8 @@ struct gcc_target
     /* Allows backends to perform additional processing when
        deciding if a class should be exported or imported.  */
     int (*import_export_class) (tree, int);
+    /* Returns true if constructors and destructors return "this".  */
+    bool (*cdtor_returns_this) (void);
   } cxx;
 
   /* Leave the boolean fields at the end.  */