aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-08-31 20:29:28 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-08-31 20:29:28 +0000
commitaf287697443400b33dbfd2297bdcf63121e7bc86 (patch)
treeee8a8ed7c7cd3d552d036001e3c45b585e180905 /gcc/cp
parent678584fc80fc69fbd3c4f5f15d484ed6006f41be (diff)
downloadgcc-af287697443400b33dbfd2297bdcf63121e7bc86.zip
gcc-af287697443400b33dbfd2297bdcf63121e7bc86.tar.gz
gcc-af287697443400b33dbfd2297bdcf63121e7bc86.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/class.c32
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl2.c6
4 files changed, 40 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b942b82..0a0fdfd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 21bdfdd..84c7587 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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. */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8267f72..a6db553 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 33a9ef5..d02180a 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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))
{