aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/objc/objc-act.c13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/objc.dg/stret-1.m62
-rw-r--r--gcc/testsuite/objc.dg/stret-2.m46
5 files changed, 124 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 38aed72..1f83435 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2004-01-17 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (build_objc_method_call): Use target
+ hooks instead of macros to determine if ..._stret
+ dispatchers should be used (NeXT runtime only).
+
2004-01-17 Roger Sayle <roger@eyesopen.com>
* builtins.c (expand_builtin_expect_jump): Fix mistake in my
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index c552bad..c135292 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -5890,21 +5890,18 @@ build_objc_method_call (int super_flag, tree method_prototype,
if (flag_next_runtime)
{
-#ifdef STRUCT_VALUE
/* If we are returning a struct in memory, and the address
of that memory location is passed as a hidden first
argument, then change which messenger entry point this
expr will call. NB: Note that sender_cast remains
unchanged (it already has a struct return type). */
- if ((TREE_CODE (ret_type) == RECORD_TYPE
- || TREE_CODE (ret_type) == UNION_TYPE)
-#if defined (DEFAULT_PCC_STRUCT_RETURN) && DEFAULT_PCC_STRUCT_RETURN == 0
- && RETURN_IN_MEMORY (ret_type)
-#endif
- && STRUCT_VALUE == 0)
+ if (!targetm.calls.struct_value_rtx (0, 0)
+ && (TREE_CODE (ret_type) == RECORD_TYPE
+ || TREE_CODE (ret_type) == UNION_TYPE)
+ && targetm.calls.return_in_memory (ret_type, 0))
sender = (super_flag ? umsg_super_stret_decl :
flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
-#endif
+
method_params = tree_cons (NULL_TREE, lookup_object,
tree_cons (NULL_TREE, selector,
method_params));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ffe6378..1847836 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-01-17 Ziemowit Laski <zlaski@apple.com>
+
+ * objc.dg/stret-1.m: New.
+ * objc.dg/stret-2.m: New.
+
2004-01-17 Andrew Pinski <pinskia@physics.uc.edu>
PR c++/11895
diff --git a/gcc/testsuite/objc.dg/stret-1.m b/gcc/testsuite/objc.dg/stret-1.m
new file mode 100644
index 0000000..427b557
--- /dev/null
+++ b/gcc/testsuite/objc.dg/stret-1.m
@@ -0,0 +1,62 @@
+/* Test for handling of struct-returning methods. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+
+#include <objc/Object.h>
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+struct astruct {
+ float a, b;
+} glob = { 1.0, 2.0 };
+
+struct bstruct {
+ float a, b, c, d, e, f;
+} globb = { 1, 2, 3, 4, 5, 6 };
+
+@interface foo : Object
+- (struct astruct) stret;
+- (struct bstruct) stretb;
+@end
+
+@implementation foo : Object
+- (struct astruct) stret { return glob; }
+- (struct bstruct) stretb { return globb; }
+@end
+
+@interface bar: foo
+- (struct astruct) stret;
+- (struct bstruct) stretb;
+@end
+
+@implementation bar
+- (struct astruct) stret { struct astruct a = [super stret]; a.b = 77; return a; }
+- (struct bstruct) stretb { struct bstruct b = [super stretb]; b.e = 99; return b; }
+@end
+
+int main(void)
+{
+ foo *obj = [foo new];
+ bar *obj2 = [bar new];
+ struct astruct loc, loc2;
+ struct bstruct locb, locb2;
+
+ loc = [obj stret];
+ CHECK_IF(loc.a == 1.0 && loc.b == 2.0);
+
+ locb = [obj stretb];
+ CHECK_IF(locb.f == 6 && locb.c == 3);
+ CHECK_IF(locb.e == 5 && locb.b == 2);
+ CHECK_IF(locb.d == 4 && locb.a == 1);
+
+ loc2 = [obj2 stret];
+ CHECK_IF(loc2.a == 1.0 && loc2.b == 77);
+
+ locb2 = [obj2 stretb];
+ CHECK_IF(locb2.f == 6 && locb2.c == 3);
+ CHECK_IF(locb2.e == 99 && locb2.b == 2);
+ CHECK_IF(locb2.d == 4 && locb2.a == 1);
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/stret-2.m b/gcc/testsuite/objc.dg/stret-2.m
new file mode 100644
index 0000000..dd9a2e8
--- /dev/null
+++ b/gcc/testsuite/objc.dg/stret-2.m
@@ -0,0 +1,46 @@
+/* Test for handling of struct-returning methods
+ for the Mac OS X ("NeXT") runtime (which uses specialized entry
+ points). */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile { target *-*-darwin* } } */
+
+#include <objc/Object.h>
+
+struct astruct {
+ float a, b;
+} glob = { 1.0, 2.0 };
+
+struct bstruct {
+ float a, b, c, d, e, f;
+} globb = { 1, 2, 3, 4, 5, 6 };
+
+@interface foo : Object
+- (struct astruct) stret;
+- (struct bstruct) stretb;
+@end
+
+@implementation foo : Object
+- (struct astruct) stret { return glob; }
+- (struct bstruct) stretb { return globb; }
+@end
+
+@interface bar: foo
+- (struct astruct) stret;
+- (struct bstruct) stretb;
+@end
+
+@implementation bar
+- (struct astruct) stret { return [super stret]; }
+- (struct bstruct) stretb { return [super stretb]; }
+@end
+
+struct astruct afunc(foo *foo_obj) {
+ return [foo_obj stret];
+}
+
+/* { dg-final { scan-assembler "objc_msgSend_stret" } } */
+/* { dg-final { scan-assembler "objc_msgSendSuper_stret" } } */
+
+/* { dg-final { scan-assembler-not "objc_msgSend\[^_S\]" } } */
+/* { dg-final { scan-assembler-not "objc_msgSendSuper\[^_\]" } } */
+