aboutsummaryrefslogtreecommitdiff
path: root/gcc/doc
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/doc
parentb938bc48d844e85327c603e01bb6c303462c2613 (diff)
downloadgcc-f05b9d93e96c2a97d80e7fc3b10df7b86c6081b0.zip
gcc-f05b9d93e96c2a97d80e7fc3b10df7b86c6081b0.tar.gz
gcc-f05b9d93e96c2a97d80e7fc3b10df7b86c6081b0.tar.bz2
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/doc')
-rw-r--r--gcc/doc/objc.texi216
1 files changed, 216 insertions, 0 deletions
diff --git a/gcc/doc/objc.texi b/gcc/doc/objc.texi
index bf32879..2bb80d1 100644
--- a/gcc/doc/objc.texi
+++ b/gcc/doc/objc.texi
@@ -20,6 +20,7 @@ several resources on the Internet that present the language.
* compatibility_alias::
* Exceptions::
* Synchronization::
+* Fast enumeration::
@end menu
@node Executing code before main
@@ -739,3 +740,218 @@ Because of the interactions between synchronization and exception
handling, you can only use @code{@@synchronized} when compiling with
exceptions enabled, that is with the command line option
@option{-fobjc-exceptions}.
+
+
+@c =========================================================================
+@node Fast enumeration
+@section Fast enumeration
+
+@menu
+* Using fast enumeration::
+* c99-like fast enumeration syntax::
+* Fast enumeration details::
+* Fast enumeration protocol::
+@end menu
+
+@c ================================
+@node Using fast enumeration
+@subsection Using fast enumeration
+
+GNU Objective-C provides support for the fast enumeration syntax:
+
+@smallexample
+ id array = @dots{};
+ id object;
+
+ for (object in array)
+ @{
+ /* Do something with 'object' */
+ @}
+@end smallexample
+
+@code{array} needs to be an Objective-C object (usually a collection
+object, for example an array, a dictionary or a set) which implements
+the ``Fast Enumeration Protocol'' (see below). If you are using a
+Foundation library such as GNUstep Base or Apple Cocoa Foundation, all
+collection objects in the library implement this protocol and can be
+used in this way.
+
+The code above would iterate over all objects in @code{array}. For
+each of them, it assigns it to @code{object}, then executes the
+@code{Do something with 'object'} statements.
+
+Here is a fully worked-out example using a Foundation library (which
+provides the implementation of @code{NSArray}, @code{NSString} and
+@code{NSLog}):
+
+@smallexample
+ NSArray *array = [NSArray arrayWithObjects: @@"1", @@"2", @@"3", nil];
+ NSString *object;
+
+ for (object in array)
+ NSLog (@@"Iterating over %@@", object);
+@end smallexample
+
+
+@c ================================
+@node c99-like fast enumeration syntax
+@subsection c99-like fast enumeration syntax
+
+A c99-like declaration syntax is also allowed:
+
+@smallexample
+ id array = @dots{};
+
+ for (id object in array)
+ @{
+ /* Do something with 'object' */
+ @}
+@end smallexample
+
+this is completely equivalent to:
+
+@smallexample
+ id array = @dots{};
+
+ @{
+ id object;
+ for (object in array)
+ @{
+ /* Do something with 'object' */
+ @}
+ @}
+@end smallexample
+
+but can save some typing.
+
+Note that the option @option{-std=c99} is not required to allow this
+syntax in Objective-C.
+
+@c ================================
+@node Fast enumeration details
+@subsection Fast enumeration details
+
+Here is a more technical description with the gory details. Consider the code
+
+@smallexample
+ for (@var{object expression} in @var{collection expression})
+ @{
+ @var{statements}
+ @}
+@end smallexample
+
+here is what happens when you run it:
+
+@itemize @bullet
+@item
+@code{@var{collection expression}} is evaluated exactly once and the
+result is used as the collection object to iterate over. This means
+it is safe to write code such as @code{for (object in [NSDictionary
+keyEnumerator]) @dots{}}.
+
+@item
+the iteration is implemented by the compiler by repeatedly getting
+batches of objects from the collection object using the fast
+enumeration protocol (see below), then iterating over all objects in
+the batch. This is faster than a normal enumeration where objects are
+retrieved one by one (hence the name ``fast enumeration'').
+
+@item
+if there are no objects in the collection, then
+@code{@var{object expression}} is set to @code{nil} and the loop
+immediately terminates.
+
+@item
+if there are objects in the collection, then for each object in the
+collection (in the order they are returned) @code{@var{object expression}}
+is set to the object, then @code{@var{statements}} are executed.
+
+@item
+@code{@var{statements}} can contain @code{break} and @code{continue}
+commands, which will abort the iteration or skip to the next loop
+iteration as expected.
+
+@item
+when the iteration ends because there are no more objects to iterate
+over, @code{@var{object expression}} is set to @code{nil}. This allows
+you to determine whether the iteration finished because a @code{break}
+command was used (in which case @code{@var{object expression}} will remain
+set to the last object that was iterated over) or because it iterated
+over all the objects (in which case @code{@var{object expression}} will be
+set to @code{nil}).
+
+@item
+@code{@var{statements}} must not make any changes to the collection
+object; if they do, it is a hard error and the fast enumeration
+terminates by invoking @code{objc_enumerationMutation}, a runtime
+function that normally aborts the program but which can be customized
+by Foundation libraries via @code{objc_set_mutation_handler} to do
+something different, such as raising an exception.
+
+@end itemize
+
+@c ================================
+@node Fast enumeration protocol
+@subsection Fast enumeration protocol
+
+If you want your own collection object to be usable with fast
+enumeration, you need to have it implement the method
+
+@smallexample
+- (unsigned long) countByEnumeratingWithState: (NSFastEnumerationState *)state
+ objects: (id *)objects
+ count: (unsigneld long)len;
+@end smallexample
+
+where @code{NSFastEnumerationState} must be defined in your code as follows:
+
+@smallexample
+typdef struct
+@{
+ unsigned long state;
+ id *itemsPtr;
+ unsigned long *mutationsPtr;
+ unsigned long extra[5];
+@} NSFastEnumerationState;
+@end smallexample
+
+If no @code{NSFastEnumerationState} is defined in your code, the
+compiler will automatically replace @code{NSFastEnumerationState *}
+with @code{struct __objcFastEnumerationState *}, where that type is
+silently defined by the compiler in an identical way. This can be
+confusing and we recommend that you define
+@code{NSFastEnumerationState} (as shown above) instead.
+
+The method is called repeatedly during a fast enumeration to retrieve
+batches of objects. Each invocation of the method should retrieve the
+next batch of objects.
+
+The return value of the method is the number of objects in the current
+batch; this should not exceed @code{len}, which is the maximum size of
+a batch as requested by the caller. The batch itself is returned in
+the @code{itemsPtr} field of the @code{NSFastEnumerationState} struct.
+
+To help with returning the objects, the @code{objects} array is a C
+array preallocated by the caller (on the stack) of size @code{len}.
+In many cases you can put the objects you want to return in that
+@code{objects} array, then do @code{itemsPtr = objects}. But you
+don't have to; if your collection already has the objects to return in
+some form of C array, it could return them from there instead.
+
+The @code{state} and @code{extra} fields of the
+@code{NSFastEnumerationState} structure allows your collection object
+to keep track of the state of the enumeration. In a simple array
+implementation, @code{state} may keep track of the index of the last
+object that was returned, and @code{extra} may be unused.
+
+The @code{mutationsPtr} field of the @code{NSFastEnumerationState} is
+used to keep track of mutations. It should point to a number; before
+working on each object, the fast enumeration loop will check that this
+number has not changed. If it has, a mutation has happened and the
+fast enumeration will abort. So, @code{mutationsPtr} could be set to
+point to some sort of version number of your collection, which is
+increased by one every time there is a change (for example when an
+object is added or removed). Or, if you are content with less strict
+mutation checks, it could point to the number of objects in your
+collection or some other value that can be checked to perform an
+approximate check that the collection has not been mutated.