summaryrefslogtreecommitdiff
path: root/gcc/testsuite/objc.dg/encode-2.m
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/objc.dg/encode-2.m
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/objc.dg/encode-2.m')
-rw-r--r--gcc/testsuite/objc.dg/encode-2.m104
1 files changed, 104 insertions, 0 deletions
diff --git a/gcc/testsuite/objc.dg/encode-2.m b/gcc/testsuite/objc.dg/encode-2.m
new file mode 100644
index 000000000..ea0ff6a7d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-2.m
@@ -0,0 +1,104 @@
+/* Test Objective-C method encodings. */
+
+/* The _encoded_ parameter offsets for Objective-C methods are
+ computed inductively as follows:
+ - The first paramter (self) has offset 0;
+ - The k-th parameter (k > 1) has offset equal to the
+ sum of:
+ - the offset of the k-1-st paramter
+ - the (void *)-promoted size of the k-1-st parameter.
+
+ Note that the encoded offsets need not correspond
+ to the actual placement of parameters (relative to 'self')
+ on the stack! Your target's ABI may have very different
+ opinions on the matter. */
+
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+
+#include "../objc-obj-c++-shared/Object1.h"
+#include "../objc-obj-c++-shared/next-mapping.h"
+
+#ifdef __NEXT_RUNTIME__
+#define METHOD Method
+#else
+#include <objc/objc-api.h>
+#define METHOD Method_t
+#define method_get_types(M) (M)->method_types
+#endif
+
+extern int sscanf(const char *str, const char *format, ...);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@interface Foo: Object
+typedef struct { float x, y; } XXPoint;
+typedef struct { float width, height; } XXSize;
+typedef struct _XXRect { XXPoint origin; XXSize size; } XXRect;
+-(id)setRect:(XXRect)r withInt:(int)i;
+-(void) char:(signed char)c float:(float)f double:(double)d long:(long)l;
+@end
+
+XXRect my_rect;
+unsigned offs1, offs2, offs3, offs4, offs5, offs6, offs7;
+
+@implementation Foo
+-(id)setRect:(XXRect)r withInt:(int)i {
+ unsigned offs = sizeof(self);
+ CHECK_IF(offs == offs3);
+ offs += sizeof(_cmd);
+ CHECK_IF(offs == offs4);
+ offs += sizeof(r);
+ CHECK_IF(offs == offs5);
+ offs += sizeof(i);
+ CHECK_IF(offs == offs1);
+ return nil;
+}
+-(void) char:(signed char)c float:(float)f double:(double)d long:(long)l {
+ unsigned offs = sizeof(self);
+ CHECK_IF(offs == offs3);
+ offs += sizeof(_cmd);
+ CHECK_IF(offs == offs4);
+ offs += sizeof((int)c);
+ CHECK_IF(offs == offs5);
+ offs += sizeof(f);
+ CHECK_IF(offs == offs6);
+ offs += sizeof(d);
+ CHECK_IF(offs == offs7);
+ offs += sizeof(l);
+ CHECK_IF(offs == offs1);
+}
+@end
+
+
+int main(void) {
+ Foo *foo = [[Foo alloc] init];
+ Class fooClass = objc_get_class("Foo");
+ METHOD meth;
+ const char *string;
+
+ meth = class_get_instance_method(fooClass, @selector(setRect:withInt:));
+ offs2 = 9999;
+
+ sscanf(method_get_types(meth), "@%u@%u:%u{_XXRect={?=ff}{?=ff}}%ui%u", &offs1, &offs2, &offs3,
+ &offs4, &offs5);
+
+ CHECK_IF(!offs2);
+ [foo setRect:my_rect withInt:123];
+
+ meth = class_get_instance_method(fooClass, @selector(char:float:double:long:));
+ offs2 = 9999;
+ if (sizeof (long) == 8)
+ string = "v%u@%u:%uc%uf%ud%uq%u";
+ else
+ string = "v%u@%u:%uc%uf%ud%ul%u";
+ sscanf(method_get_types(meth), string, &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6, &offs7);
+ CHECK_IF(!offs2);
+ [foo char:'c' float:2.3 double:3.5 long:2345L];
+
+ return 0;
+}
+
+#include "../objc-obj-c++-shared/Object1-implementation.h"