summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>2004-08-04 15:33:51 +0000
committerpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>2004-08-04 15:33:51 +0000
commit853b76408afac56f049f4720e38b2853d632cc74 (patch)
treec6669d1a536c5ee91ed55f661a6f7a5a2bd88e47 /gcc/cp
parent0f8db1b151885a48c38fbb5acb58e8ac481056b3 (diff)
downloadgcc-853b76408afac56f049f4720e38b2853d632cc74.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85561 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog21
-rw-r--r--gcc/cp/Make-lang.in4
-rw-r--r--gcc/cp/cp-tree.h10
-rw-r--r--gcc/cp/decl.c77
-rw-r--r--gcc/cp/method.c13
-rw-r--r--gcc/cp/optimize.c8
-rw-r--r--gcc/cp/semantics.c7
7 files changed, 109 insertions, 31 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e82e5005d00..81ac4397627 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 1ce05dac03c..52337392d0b 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -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)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 5b499256238..e2c94f25ed2 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 8c85e71003d..0f489976a63 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 7a2a7624fd8..317790e877f 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -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:
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index b94270eabd6..7ccfaffbf0d 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -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);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 606fe5fc3f6..cf61c221e72 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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);
}
}