hooks.c (hook_bool_void_true): New function.

* hooks.c (hook_bool_void_true): New function.
	* hooks.h (hook_bool_void_true): Declare.
	* target-def.h (TARGET_CXX): Add
	TARGET_CXX_KEY_METHOD_MAY_BE_INLINE.
	* target.h (struct cxx): Add key_method_may_be_inline.
	* config/arm/arm.c (arm_cxx_key_method_may_be_inline): New
	function.
	(TARGET_CXX_KEY_METHOD_MAY_BE_INLINE): New macro.
	* config/arm/bpabi.h: Use __THUMB_INTERWORK__ instead of
	__THUMB_INTERWORK.

 	* class.c (key_method): Rename to ...
	(determine_key_method): ... this.
	(finish_struct_1): Adjust accordingly.
	* cp-tree.h (key_method): Declare.
	* decl2.c (maybe_emit_vtables): Determine the key method here if
	it has not already been done.

	* g++.dg/abi/key1.C: New test.

From-SVN: r86843
This commit is contained in:
Mark Mitchell 2004-08-31 20:29:28 +00:00 committed by Mark Mitchell
parent 678584fc80
commit af28769744
12 changed files with 113 additions and 10 deletions

View File

@ -1,3 +1,16 @@
2004-08-31 Mark Mitchell <mark@codesourcery.com>
* hooks.c (hook_bool_void_true): New function.
* hooks.h (hook_bool_void_true): Declare.
* target-def.h (TARGET_CXX): Add
TARGET_CXX_KEY_METHOD_MAY_BE_INLINE.
* target.h (struct cxx): Add key_method_may_be_inline.
* config/arm/arm.c (arm_cxx_key_method_may_be_inline): New
function.
(TARGET_CXX_KEY_METHOD_MAY_BE_INLINE): New macro.
* config/arm/bpabi.h: Use __THUMB_INTERWORK__ instead of
__THUMB_INTERWORK.
2004-08-31 Denis Chertykov <denisc@overta.ru>
PR target/15417

View File

@ -1,3 +1,12 @@
2004-08-31 Mark Mitchell <mark@codesourcery.com>
* class.c (key_method): Rename to ...
(determine_key_method): ... this.
(finish_struct_1): Adjust accordingly.
* cp-tree.h (key_method): Declare.
* decl2.c (maybe_emit_vtables): Determine the key method here if
it has not already been done.
2004-08-31 Ziemowit Laski <zlaski@apple.com>
* Make-lang.in (CXX_AND_OBJCXX_OBJS): Add cp/cp-objcp-common.o.

View File

@ -4886,11 +4886,11 @@ layout_class_type (tree t, tree *virtuals_p)
splay_tree_delete (empty_base_offsets);
}
/* Returns the virtual function with which the vtable for TYPE is
emitted, or NULL_TREE if that heuristic is not applicable to TYPE. */
/* Determine the "key method" for the class type indicated by TYPE,
and set CLASSTYPE_KEY_METHOD accordingly. */
static tree
key_method (tree type)
void
determine_key_method (tree type)
{
tree method;
@ -4898,16 +4898,23 @@ key_method (tree type)
|| processing_template_decl
|| CLASSTYPE_TEMPLATE_INSTANTIATION (type)
|| CLASSTYPE_INTERFACE_KNOWN (type))
return NULL_TREE;
return;
/* The key method is the first non-pure virtual function that is not
inline at the point of class definition. On some targets the
key function may not be inline; those targets should not call
this function until the end of the translation unit. */
for (method = TYPE_METHODS (type); method != NULL_TREE;
method = TREE_CHAIN (method))
if (DECL_VINDEX (method) != NULL_TREE
&& ! DECL_DECLARED_INLINE_P (method)
&& ! DECL_PURE_VIRTUAL_P (method))
return method;
{
CLASSTYPE_KEY_METHOD (type) = method;
break;
}
return NULL_TREE;
return;
}
/* Perform processing required when the definition of T (a class type)
@ -4950,7 +4957,16 @@ finish_struct_1 (tree t)
/* Find the key method. */
if (TYPE_CONTAINS_VPTR_P (t))
{
CLASSTYPE_KEY_METHOD (t) = key_method (t);
/* The Itanium C++ ABI permits the key method to be chosen when
the class is defined -- even though the key method so
selected may later turn out to be an inline function. On
some systems (such as ARM Symbian OS) the key method cannot
be determined until the end of the translation unit. On such
systems, we leave CLASSTYPE_KEY_METHOD set to NULL, which
will cause the class to be added to KEYED_CLASSES. Then, in
finish_file we will determine the key method. */
if (targetm.cxx.key_method_may_be_inline ())
determine_key_method (t);
/* If a polymorphic class has no key method, we may emit the vtable
in every translation unit where the class definition appears. */

View File

@ -3673,6 +3673,7 @@ extern void debug_class (tree);
extern void debug_thunks (tree);
extern tree cp_fold_obj_type_ref (tree, tree);
extern void set_linkage_according_to_type (tree, tree);
extern void determine_key_method (tree);
/* in cvt.c */
extern tree convert_to_reference (tree, tree, int, int, tree);

View File

@ -1559,6 +1559,12 @@ maybe_emit_vtables (tree ctype)
if (TREE_TYPE (primary_vtbl) == void_type_node)
return false;
/* On some targets, we cannot determine the key method until the end
of the translation unit -- which is when this function is
called. */
if (!targetm.cxx.key_method_may_be_inline ())
determine_key_method (ctype);
/* See if any of the vtables are needed. */
for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl))
{

View File

@ -8528,6 +8528,16 @@ the address of the object created/destroyed. The default is to return
@code{false}.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_CXX_KEY_METHOD_MAY_BE_INLINE (void)
This hook returns true if the key method for a class (i.e., the method
which, if defined in the current translation unit, causes the virtual
table to be emitted) may be an inline function. Under the standard
Itanium C++ ABI the key method may be an inline function so long as
the function is not declared inline in the class definition. Under
some variants of the ABI, an inline function can never be the key
method. The default is to return @code{true}.
@end deftypefn
@node Misc
@section Miscellaneous Parameters
@cindex parameters, miscellaneous

View File

@ -41,7 +41,14 @@ hook_bool_void_false (void)
return false;
}
/* The same, but formally returning NO_REGS. */
/* Generic hook that takes no arguments and returns true. */
bool
hook_bool_void_true (void)
{
return true;
}
/* Generic hook that takes no arguments and returns NO_REGS. */
int
hook_int_void_no_regs (void)
{

View File

@ -25,6 +25,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "machmode.h"
extern bool hook_bool_void_false (void);
extern bool hook_bool_void_true (void);
extern bool hook_bool_bool_false (bool);
extern bool hook_bool_mode_false (enum machine_mode);
extern bool hook_bool_tree_false (tree);

View File

@ -437,6 +437,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_CXX_CDTOR_RETURNS_THIS hook_bool_void_false
#endif
#ifndef TARGET_CXX_KEY_METHOD_MAY_BE_INLINE
#define TARGET_CXX_KEY_METHOD_MAY_BE_INLINE hook_bool_void_true
#endif
#define TARGET_CXX \
{ \
TARGET_CXX_GUARD_TYPE, \
@ -444,7 +448,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_CXX_GET_COOKIE_SIZE, \
TARGET_CXX_COOKIE_HAS_SIZE, \
TARGET_CXX_IMPORT_EXPORT_CLASS, \
TARGET_CXX_CDTOR_RETURNS_THIS \
TARGET_CXX_CDTOR_RETURNS_THIS, \
TARGET_CXX_KEY_METHOD_MAY_BE_INLINE \
}
/* The whole shebang. */

View File

@ -516,6 +516,11 @@ struct gcc_target
int (*import_export_class) (tree, int);
/* Returns true if constructors and destructors return "this". */
bool (*cdtor_returns_this) (void);
/* Returns true if the key method for a class can be an inline
function, so long as it is not declared inline in the class
itself. Returning true is the behavior required by the Itanium
C++ ABI. */
bool (*key_method_may_be_inline) (void);
} cxx;
/* Leave the boolean fields at the end. */

View File

@ -1,3 +1,7 @@
2004-08-31 Mark Mitchell <mark@codesourcery.com>
* g++.dg/abi/key1.C: New test.
2004-08-31 Richard Henderson <rth@redhat.com>
* g++.dg/other/offsetof1.C: Include cstddef, use non-builtin

View File

@ -0,0 +1,26 @@
// On ARM EABI platforms, key methods may never be inline.
// { dg-do compile { target arm*-*-eabi* arm*-*-symbianelf* } }
// { dg-final { scan-assembler-not _ZTV1S } }
// { dg-final { scan-assembler-not _ZTV1T } }
// { dg-final { scan-assembler _ZTV1U } }
struct S {
virtual void f();
};
inline void S::f() {}
struct T {
virtual void g();
virtual void h();
};
inline void T::g() {}
struct U {
virtual void i();
virtual void j();
};
inline void U::i() {}
void U::j () {}