diff options
author | Nicola Pero <nicola.pero@meta-innovation.com> | 2010-10-06 10:10:14 +0000 |
---|---|---|
committer | Nicola Pero <nicola@gcc.gnu.org> | 2010-10-06 10:10:14 +0000 |
commit | f05b9d93e96c2a97d80e7fc3b10df7b86c6081b0 (patch) | |
tree | 9dd722f6e098569456083c38fb1b313e672cd799 /gcc/testsuite/objc.dg/foreach-4.m | |
parent | b938bc48d844e85327c603e01bb6c303462c2613 (diff) | |
download | gcc-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.m | 259 |
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; +} |