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:
parent
678584fc80
commit
af28769744
12 changed files with 113 additions and 10 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
26
gcc/testsuite/g++.dg/abi/key1.C
Normal file
26
gcc/testsuite/g++.dg/abi/key1.C
Normal 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 () {}
|
Loading…
Add table
Reference in a new issue