summaryrefslogtreecommitdiff
path: root/gcc/testsuite/objc.dg/foreach-4.m
diff options
context:
space:
mode:
authorNicola Pero <nicola.pero@meta-innovation.com>2010-10-06 10:10:14 +0000
committerNicola Pero <nicola@gcc.gnu.org>2010-10-06 10:10:14 +0000
commitf05b9d93e96c2a97d80e7fc3b10df7b86c6081b0 (patch)
tree9dd722f6e098569456083c38fb1b313e672cd799 /gcc/testsuite/objc.dg/foreach-4.m
parentb938bc48d844e85327c603e01bb6c303462c2613 (diff)
downloadgcc-f05b9d93e96c2a97d80e7fc3b10df7b86c6081b0.tar.gz
In gcc/: 2010-10-06 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/: 2010-10-06 Nicola Pero <nicola.pero@meta-innovation.com> Implemented fast enumeration for Objective-C. * c-parser.c (objc_could_be_foreach_context): New. (c_lex_one_token): Recognize RID_IN keyword in a potential Objective-C foreach context. (c_parser_declaration_or_fndef): Added parameter. Accept Objective-C RID_IN keyword as terminating a declaration; in that case, return the declaration in the new parameter. (c_parser_extenral_declaration): Updated calls to c_parser_declaration_or_fndef. (c_parser_declaration_or_fndef): Same change. (c_parser_compound_statement_nostart): Same change. (c_parser_label): Same change. (c_parser_objc_methodprotolist): Same change. (c_parser_omp_for_loop): Same change. (c_parser_for_statement): Detect and parse Objective-C foreach statements. (c_parser_omp_for_loop): Updated call to check_for_loop_decls(). * c-decl.c (check_for_loop_decls): Added parameter to allow ObjC fast enumeration parsing code to turn off the c99 error but still perform checks on the loop declarations. * c-tree.h (check_for_loop_decls): Updated declaration. * doc/objc.texi: Document fast enumeration. In gcc/c-family/: 2010-10-06 Nicola Pero <nicola.pero@meta-innovation.com> Implemented fast enumeration for Objective-C. * c-common.h (objc_finish_foreach_loop): New. * stub-objc.c (objc_finish_foreach_loop): New. In gcc/objc/: 2010-10-06 Nicola Pero <nicola.pero@meta-innovation.com> Implemented fast enumeration for Objective-C. * objc-act.c (build_fast_enumeration_state_template): New. (TAG_ENUMERATION_MUTATION): New. (TAG_FAST_ENUMERATION_STATE): New. (synth_module_prologue): Call build_fast_enumeration_state_template() and set up objc_enumeration_mutation_decl. (objc_create_temporary_var): Allow providing a name to temporary variables. (objc_build_exc_ptr): Updated calls to objc_create_temporary_var(). (next_sjlj_build_try_catch_finally): Same change. (objc_finish_foreach_loop): New. * objc-act.h: Added OCTI_FAST_ENUM_STATE_TEMP, OCTI_ENUM_MUTATION_DECL, objc_fast_enumeration_state_template, objc_enumeration_mutation_decl. Merge from 'apple/trunk' branch on FSF servers. 2006-04-12 Fariborz Jahanian <fjahanian@apple.com> Radar 4507230 * objc-act.c (objc_type_valid_for_messaging): New routine to check for valid objc object types. (objc_finish_foreach_loop): Check for invalid objc objects in foreach header. In gcc/testsuite/: 2010-10-05 Nicola Pero <nicola.pero@meta-innovation.com> Implemented fast enumeration for Objective-C. * objc.dg/foreach-1.m: New. * objc.dg/foreach-2.m: New. * objc.dg/foreach-3.m: New. * objc.dg/foreach-4.m: New. * objc.dg/foreach-5.m: New. * objc.dg/foreach-6.m: New. * objc.dg/foreach-7.m: New. Merge from 'apple/trunk' branch on FSF servers: 2006-04-13 Fariborz Jahanian <fjahanian@apple.com> Radar 4502236 * objc.dg/objc-foreach-5.m: New. 2006-04-12 Fariborz Jahanian <fjahanian@apple.com> Radar 4507230 * objc.dg/objc-foreach-4.m: New. 2006-03-13 Fariborz Jahanian <fjahanian@apple.com> Radar 4472881 * objc.dg/objc-foreach-3.m: New. 2005-03-07 Fariborz Jahanian <fjahanian@apple.com> Radar 4468498 * objc.dg/objc-foreach-2.m: New. 2006-02-15 Fariborz Jahanian <fjahanian@apple.com> Radar 4294910 * objc.dg/objc-foreach-1.m: New In libobjc/: 2010-10-06 Nicola Pero <nicola.pero@meta-innovation.com> Implemented fast enumeration for Objective-C. * Makefile.in (C_SOURCE_FILES): Added objc-foreach.c. (OBJC_H): Added runtime.h * objc-foreach.c: New file. * objc/runtime.h: New file. From-SVN: r165019
Diffstat (limited to 'gcc/testsuite/objc.dg/foreach-4.m')
-rw-r--r--gcc/testsuite/objc.dg/foreach-4.m259
1 files changed, 259 insertions, 0 deletions
diff --git a/gcc/testsuite/objc.dg/foreach-4.m b/gcc/testsuite/objc.dg/foreach-4.m
new file mode 100644
index 00000000000..c9cd977b095
--- /dev/null
+++ b/gcc/testsuite/objc.dg/foreach-4.m
@@ -0,0 +1,259 @@
+/* Test basic Objective-C foreach syntax. This tests iterations, with
+ the declaration syntax 'for (id object in array) statements'
+*/
+/* FIXME: Run this test with the NeXT runtime as well. */
+/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+/* { dg-do run } */
+
+#include <objc/objc.h>
+#include <objc/Object.h>
+#include <objc/NXConstStr.h>
+#include <stdlib.h>
+extern void abort (void);
+/*
+struct __objcFastEnumerationState
+{
+ unsigned long state;
+ id *itemsPtr;
+ unsigned long *mutationsPtr;
+ unsigned long extra[5];
+};
+*/
+
+ /* A mini-array implementation that can be used to test fast
+ enumeration. You create the array with some objects; you can
+ mutate the array, and you can fast-enumerate it.
+ */
+@interface MyArray : Object
+{
+ unsigned int length;
+ id *objects;
+ unsigned long mutated;
+}
+- (id) initWithLength: (unsigned int)l objects: (id *)o;
+- (void) mutate;
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
+ objects:(id *)stackbuf
+ count:(unsigned long)len;
+@end
+
+@implementation MyArray : Object
+- (id) initWithLength: (unsigned int)l
+ objects: (id *)o
+{
+ length = l;
+ objects = o;
+ mutated = 0;
+}
+- (void) mutate
+{
+ mutated = 1;
+}
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState*)state
+ objects: (id*)stackbuf
+ count: (unsigned long)len
+{
+ unsigned long i, batch_size;
+
+ /* We keep how many objects we served in the state->state counter. So the next batch
+ will contain up to length - state->state objects. */
+ batch_size = length - state->state;
+
+ /* Make obvious adjustments. */
+ if (batch_size < 0)
+ batch_size = 0;
+
+ if (batch_size > len)
+ batch_size = len;
+
+ /* Copy the objects. */
+ for (i = 0; i < batch_size; i++)
+ stackbuf[i] = objects[i];
+
+ state->state += batch_size;
+ state->itemsPtr = stackbuf;
+ state->mutationsPtr = &mutated;
+
+ return batch_size;
+}
+@end
+
+int main (void)
+{
+ MyArray *array;
+ int test_variable, counter, i;
+ id *objects;
+
+ array = [[MyArray alloc] initWithLength: 0
+ objects: NULL];
+
+ /* Test that an empty array does nothing. */
+ for (id object in array)
+ abort ();
+
+ /* Test iterating over 1 object. */
+ objects = malloc (sizeof (id) * 1);
+ objects[0] = @"One Object";
+
+ array = [[MyArray alloc] initWithLength: 1
+ objects: objects];
+
+ for (id object in array)
+ printf ("%p\n", object);
+
+ /* Test iterating over 20 objects. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+
+ for (id object in array)
+ printf ("%p\n", object);
+
+ /* Test iterating over 200 objects. */
+ objects = malloc (sizeof (id) * 200);
+ for (i = 0; i < 200; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 200
+ objects: objects];
+
+ counter = 0;
+ for (id object in array)
+ {
+ if (object != nil)
+ counter++;
+ }
+
+ if (counter != 200)
+ abort ();
+
+ printf ("Counter was %d (should be 200)\n", counter);
+
+ /* Test iterating again over the same array. */
+ counter = 0;
+ for (id object in array)
+ {
+ if (object != nil)
+ counter++;
+ }
+
+ if (counter != 200)
+ abort ();
+
+ printf ("Counter was %d (should be 200)\n", counter);
+
+ /* Test nested iterations. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ for (id another_object in array)
+ if (another_object != nil)
+ counter++;
+ }
+
+ printf ("Counter was %d (should be 400)\n", counter);
+
+ if (counter != 400)
+ abort ();
+
+ /* Test 'continue'. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ if (counter == 15)
+ continue;
+
+ counter++;
+ }
+
+ printf ("Counter was %d (should be 15)\n", counter);
+
+ if (counter != 15)
+ abort ();
+
+ /* Test 'break'. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ counter++;
+
+ if (counter == 15)
+ break;
+ }
+
+ printf ("Counter was %d (should be 15)\n", counter);
+
+ if (counter != 15)
+ abort ();
+
+ /* Test 'break' and 'continue' in nested iterations. */
+ objects = malloc (sizeof (id) * 20);
+ for (i = 0; i < 20; i++)
+ objects[i] = @"object";
+
+ array = [[MyArray alloc] initWithLength: 20
+ objects: objects];
+ counter = 0;
+ for (id object in array)
+ {
+ int local_counter = 0;
+
+ /* Each internal loop should increase counter by 24. */
+ for (id another_object in array)
+ {
+ local_counter++;
+
+ if (local_counter == 10)
+ {
+ counter = counter + 20;
+ break;
+ }
+
+ if (local_counter >= 5)
+ continue;
+
+ counter++;
+ }
+
+ /* Exit after 4 iterations. */
+ if (counter == 96)
+ break;
+ }
+
+ printf ("Counter was %d (should be 96)\n", counter);
+
+ if (counter != 96)
+ abort ();
+
+ /* Test that C for loops still work. */
+ test_variable = 0;
+
+ for (counter = 0; counter < 4; counter++)
+ test_variable++;
+
+ if (test_variable != 4)
+ abort ();
+
+ return 0;
+}