aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/objc/ChangeLog7
-rw-r--r--gcc/objc/objc-act.c45
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/objc.dg/encode-5.m78
4 files changed, 130 insertions, 6 deletions
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index b0216ae..04b94c0 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,10 @@
+2004-12-30 Ziemowit Laski <zlaski@apple.com>
+
+ PR objc/18971
+ * objc-act.c (get_arg_type_list, start_method_def): Decay
+ array arguments into pointers.
+ (gen_type_name_0): Learn to pretty-print array types.
+
2004-12-15 Ziemowit Laski <zlaski@apple.com>
* objc-act.c (build_private_template): Change to return 'void'; do
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index b77e441..0952500 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -5300,6 +5300,10 @@ get_arg_type_list (tree meth, int context, int superflag)
{
tree arg_type = TREE_VALUE (TREE_TYPE (akey));
+ /* Decay arrays into pointers. */
+ if (TREE_CODE (arg_type) == ARRAY_TYPE)
+ arg_type = build_pointer_type (TREE_TYPE (arg_type));
+
chainon (arglist, build_tree_list (NULL_TREE, arg_type));
}
@@ -7473,9 +7477,13 @@ start_method_def (tree method)
parmlist = METHOD_SEL_ARGS (method);
while (parmlist)
{
- tree parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist),
- TREE_VALUE (TREE_TYPE (parmlist)));
+ tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
+
+ /* Decay arrays into pointers. */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ type = build_pointer_type (TREE_TYPE (type));
+ parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
objc_push_parm (parm);
parmlist = TREE_CHAIN (parmlist);
}
@@ -7941,14 +7949,39 @@ gen_type_name_0 (tree type)
if (TYPE_P (type) && TYPE_NAME (type))
type = TYPE_NAME (type);
- else if (POINTER_TYPE_P (type))
+ else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
{
- gen_type_name_0 (TREE_TYPE (type));
+ tree inner = TREE_TYPE (type);
+
+ while (TREE_CODE (inner) == ARRAY_TYPE)
+ inner = TREE_TYPE (inner);
+
+ gen_type_name_0 (inner);
- if (!POINTER_TYPE_P (TREE_TYPE (type)))
+ if (!POINTER_TYPE_P (inner))
strcat (errbuf, " ");
- strcat (errbuf, "*");
+ if (POINTER_TYPE_P (type))
+ strcat (errbuf, "*");
+ else
+ while (type != inner)
+ {
+ strcat (errbuf, "[");
+
+ if (TYPE_DOMAIN (type))
+ {
+ char sz[20];
+
+ sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
+ (TREE_INT_CST_LOW
+ (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
+ strcat (errbuf, sz);
+ }
+
+ strcat (errbuf, "]");
+ type = TREE_TYPE (type);
+ }
+
goto exit_function;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c381350..5bb8957 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2004-12-30 Alexander Malmberg <alexander@malmberg.org>
+ Ziemowit Laski <zlaski@apple.com>
+
+ PR objc/18971
+ * objc.dg/encode-5.m: New test.
+
2004-12-29 Richard Henderson <rth@redhat.com>
* gcc.dg/20040813-1.c: Disable for alpha and ia64.
diff --git a/gcc/testsuite/objc.dg/encode-5.m b/gcc/testsuite/objc.dg/encode-5.m
new file mode 100644
index 0000000..f2cb693
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-5.m
@@ -0,0 +1,78 @@
+/* Check if array arguments of ObjC methods are decayed to pointer types
+ in a proper fashion:
+ (1) The _encodings_ for the array arguments should remain to be '[4i]' and
+ such, since this has been the case since at least gcc 3.3.
+ (2) However, when building the static C functions out of ObjC method signatures,
+ we need to decay the arrays into pointers (as C does).
+ (3) If array size is not known (e.g., 'int a[]'), then the type shall be
+ encoded as a pointer. */
+
+/* Contributed by Alexander Malmberg <alexander@malmberg.org> */
+
+#include <objc/Object.h>
+#include <stdlib.h>
+#include <stdio.h>
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+#ifdef __NEXT_RUNTIME__
+#define METHOD Method
+#define OBJC_GETCLASS objc_getClass
+#define CLASS_GETINSTANCEMETHOD class_getInstanceMethod
+#else
+#include <objc/objc-api.h>
+#define METHOD Method_t
+#define OBJC_GETCLASS objc_get_class
+#define CLASS_GETINSTANCEMETHOD class_get_instance_method
+#endif
+
+@interface Test : Object
+{ float j; }
+-(void) test2: (int [5])a with: (int [])b;
+-(id) test3: (Test **)b; /* { dg-warning "previous declaration of .\\-\\(id\\)test3:\\(Test \\*\\*\\)b." } */
+@end
+
+@implementation Test
+-(void) test2: (int [5])a with: (int [])b
+{
+ a[3] = *b;
+}
+-(void) test3: (Test [3][4])b { /* { dg-warning "conflicting types for .\\-\\(void\\)test3:\\(Test \\\[3\\\]\\\[4\\\]\\)b." } */
+}
+@end
+
+int bb[6] = { 0, 1, 2, 3, 4, 5 };
+int *b = bb;
+Test *cc[4];
+Test **c = cc;
+
+int offs1, offs2, offs3, offs4, offs5, offs6;
+
+int main(int argc, char **argv)
+{
+ Class testClass = OBJC_GETCLASS("Test");
+ METHOD meth;
+
+ cc[0] = [Test new];
+ CHECK_IF (bb[3] == 3);
+ [*c test2: b with: bb + 4];
+ CHECK_IF (bb[3] == 4);
+ bb[3] = 0;
+ [*c test2: bb with: bb + 5];
+ CHECK_IF (bb[3] == 5);
+
+ meth = CLASS_GETINSTANCEMETHOD(testClass, @selector(test2:with:));
+ offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1;
+ sscanf(meth->method_types, "v%d@%d:%d[%di]%d^i%d", &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6);
+ CHECK_IF (!offs2 && offs4 == 5 && offs3 > 0);
+ CHECK_IF (offs5 == 2 * offs3 && offs6 == 3 * offs3 && offs1 == 4 * offs3);
+
+ meth = CLASS_GETINSTANCEMETHOD(testClass, @selector(test3:));
+ offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1;
+ sscanf(meth->method_types, "v%d@%d:%d[%d[%d{Test=#f}]]%d", &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6);
+ CHECK_IF (!offs2 && offs4 == 3 && offs5 == 4 && offs3 > 0);
+ CHECK_IF (offs6 == 2 * offs3 && offs1 == 3 * offs3);
+
+ return 0;
+}