mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-18 01:20:48 +08:00
target-def.h (TARGET_CXX_CDTOR_RETURNS_THIS): Define.
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
This commit is contained in:
parent
20c176ab4b
commit
44d10c1002
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user