/* GNU Objective-C Runtime API - Modern API
- Copyright (C) 2010 Free Software Foundation, Inc.
+ Copyright (C) 2010-2013 Free Software Foundation, Inc.
Contributed by Nicola Pero <nicola.pero@meta-innovation.com>
This file is part of GCC.
/*
This file declares the "modern" GNU Objective-C Runtime API.
- Include this file to use it.
-
- This API is replacing the "traditional" GNU Objective-C Runtime API
- (declared in objc/objc-api.h) which is the one supported by older
- versions of the GNU Objective-C Runtime. The "modern" API is very
- similar to the API used by the modern Apple/NeXT runtime.
-
- Because the two APIs have some conflicting definitions (in
- particular, Method and Category are defined differently) you should
- include either objc/objc-api.h (to use the traditional GNU
- Objective-C Runtime API) or objc/runtime.h (to use the modern GNU
- Objective-C Runtime API), but not both.
-*/
-#ifdef __objc_api_INCLUDE_GNU
-# error You can not include both objc/objc-api.h and objc/runtime.h. Include objc/objc-api.h for the traditional GNU Objective-C Runtime API and objc/runtime.h for the modern one.
-#endif
-
-/* TODO: This file is incomplete. */
+ This API replaced the "traditional" GNU Objective-C Runtime API
+ (which used to be declared in objc/objc-api.h) which is the one
+ supported by older versions of the GNU Objective-C Runtime. The
+ "modern" API is very similar to the API used by the modern
+ Apple/NeXT runtime.
+*/
#include "objc.h"
#include "objc-decls.h"
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
/* An 'Ivar' represents an instance variable. It holds information
about the name, type and offset of the instance variable. */
typedef struct objc_ivar *Ivar;
"<null selector>". */
objc_EXPORT const char *sel_getName (SEL selector);
-/* Return the type of a given selector.
+/* Return the type of a given selector. Return NULL if selector is
+ NULL.
Compatibility Note: the Apple/NeXT runtime has untyped selectors,
so it does not have this function, which is specific to the GNU
Runtime. */
-objc_EXPORT const char *sel_getType (SEL selector);
+objc_EXPORT const char *sel_getTypeEncoding (SEL selector);
/* This is the same as sel_registerName (). Please use
sel_registerName () instead. */
/* Register a selector with a given name (but unspecified types). If
you know the types, it is better to call sel_registerTypedName().
- If a selector with this name already exists, it is returned. */
+ If a selector with this name and no types already exists, it is
+ returned. Note that this function should really be called
+ 'objc_registerSelector'. Return NULL if 'name' is NULL. */
objc_EXPORT SEL sel_registerName (const char *name);
/* Register a selector with a given name and types. If a selector
- with this name and types already exists, it is returned.
+ with this name and types already exists, it is returned. Note that
+ this function should really be called 'objc_registerTypedSelector',
+ and it's called 'sel_registerTypedName' only for consistency with
+ 'sel_registerName'. Return NULL if 'name' is NULL.
Compatibility Note: the Apple/NeXT runtime has untyped selectors,
so it does not have this function, which is specific to the GNU
if not. */
objc_EXPORT BOOL sel_isEqual (SEL first_selector, SEL second_selector);
+/* Return all the selectors with the supplied name. In the GNU
+ runtime, selectors are typed and there may be multiple selectors
+ with the same name but a different type. The return value of the
+ function is a pointer to an area, allocated with malloc(), that
+ contains all the selectors with the supplier name known to the
+ runtime. The list is terminated by NULL. Optionally, if you pass
+ a non-NULL 'numberOfReturnedSelectors' pointer, the unsigned int
+ that it points to will be filled with the number of selectors
+ returned.
+
+ Compatibility Note: the Apple/NeXT runtime has untyped selectors,
+ so it does not have this function, which is specific to the GNU
+ Runtime. */
+objc_EXPORT SEL * sel_copyTypedSelectorList (const char *name,
+ unsigned int *numberOfReturnedSelectors);
+
+/* Return a selector with name 'name' and a non-zero type encoding, if
+ there is a single selector with a type, and with that name,
+ registered with the runtime. If there is no such selector, or if
+ there are multiple selectors with the same name but conflicting
+ types, NULL is returned. Return NULL if 'name' is NULL.
+
+ This is useful if you have the name of the selector, and would
+ really like to get a selector for it that includes the type
+ encoding. Unfortunately, if the program contains multiple selector
+ with the same name but different types, sel_getTypedSelector can
+ not possibly know which one you need, and so will return NULL.
+
+ Compatibility Note: the Apple/NeXT runtime has untyped selectors,
+ so it does not have this function, which is specific to the GNU
+ Runtime. */
+objc_EXPORT SEL sel_getTypedSelector (const char *name);
+
/** Implementation: the following functions are in objects.c. */
include instance variables of superclasses. The list is terminated
by NULL. Optionally, if you pass a non-NULL
'numberOfReturnedIvars' pointer, the unsigned int that it points to
- will be filled with the number of instance variables returned. */
+ will be filled with the number of instance variables returned.
+ Return NULL for classes still in construction (ie, allocated using
+ objc_allocatedClassPair() but not yet registered with the runtime
+ using objc_registerClassPair()). */
objc_EXPORT Ivar * class_copyIvarList (Class class_, unsigned int *numberOfReturnedIvars);
+/* Add an instance variable with name 'ivar_name' to class 'class_',
+ where 'class_' is a class in construction that has been created
+ using objc_allocateClassPair() and has not been registered with the
+ runtime using objc_registerClassPair() yet. You can not add
+ instance variables to classes already registered with the runtime.
+ 'size' is the size of the instance variable, 'log_2_of_alignment'
+ the alignment as a power of 2 (so 0 means alignment to a 1 byte
+ boundary, 1 means alignment to a 2 byte boundary, 2 means alignment
+ to a 4 byte boundary, etc), and 'type' the type encoding of the
+ variable type. You can use sizeof(), log2(__alignof__()) and
+ @encode() to determine the right 'size', 'alignment' and 'type' for
+ your instance variable. For example, to add an instance variable
+ name "my_variable" and of type 'id', you can use:
+
+ class_addIvar (class, "my_variable", sizeof (id), log2 ( __alignof__ (id)),
+ @encode (id));
+
+ Return YES if the variable was added, and NO if not. In
+ particular, return NO if 'class_' is Nil, or a meta-class or a
+ class not in construction. Return Nil also if 'ivar_name' or
+ 'type' is NULL, or 'size' is 0.
+ */
+objc_EXPORT BOOL class_addIvar (Class class_, const char * ivar_name, size_t size,
+ unsigned char log_2_of_alignment, const char *type);
+
/* Return the name of the property. Return NULL if 'property' is
NULL. */
objc_EXPORT const char * property_getName (Property property);
This function is not safe to call in a multi-threaded environment
because other threads may be trying to use the get unknown class
handler while you change it! */
+objc_EXPORT
objc_get_unknown_class_handler
objc_setGetUnknownClassHandler (objc_get_unknown_class_handler new_handler);
-
/* Return the class with name 'name', if it is already registered with
the runtime. If it is not registered, and
objc_setGetUnknownClassHandler() has been called to set a handler
the runtime. Return Nil if not. This function does not call the
objc_get_unknown_class_handler function if the class is not
found. */
-objc_EXPORT Class objc_lookupClass (const char *name);
+objc_EXPORT Class objc_lookUpClass (const char *name);
/* Return the meta class associated to the class with name 'name', if
it is already registered with the runtime. First, it finds the
is Nil, return NO. */
objc_EXPORT BOOL class_isMetaClass (Class class_);
-/* Return the superclass of 'class_'. If 'class_' is Nil, or it is a root
- class, return Nil.
-
- TODO: It may be worth to define this inline, since it is usually
- used in loops when traversing the class hierarchy. */
+/* Return the superclass of 'class_'. If 'class_' is Nil, or it is a
+ root class, return Nil. This function also works if 'class_' is a
+ class being constructed, that is, a class returned by
+ objc_allocateClassPair() but before it has been registered with the
+ runtime using objc_registerClassPair(). */
objc_EXPORT Class class_getSuperclass (Class class_);
/* Return the 'version' number of the class, which is an integer that
objc_EXPORT void
method_exchangeImplementations (Method method_a, Method method_b);
+/* Create a new class/meta-class pair. This function is called to
+ create a new class at runtime. The class is created with
+ superclass 'superclass' (use 'Nil' to create a new root class) and
+ name 'class_name'. 'extraBytes' can be used to specify some extra
+ space for indexed variables to be added at the end of the class and
+ meta-class objects (it is recommended that you set extraBytes to
+ 0). Once you have created the class, it is not usable yet. You
+ need to add any instance variables (by using class_addIvar()), any
+ instance methods (by using class_addMethod()) and any class methods
+ (by using class_addMethod() on the meta-class, as in
+ class_addMethod (object_getClass (class), method)) that are
+ required, and then you need to call objc_registerClassPair() to
+ activate the class. If you need to create a hierarchy of classes,
+ you need to create and register them one at a time. You can not
+ create a new class using another class in construction as
+ superclass. Return Nil if 'class-name' is NULL or if a class with
+ that name already exists or 'superclass' is a class still in
+ construction.
+
+ Implementation Note: in the GNU runtime, allocating a class pair
+ only creates the structures for the class pair, but does not
+ register anything with the runtime. The class is registered with
+ the runtime only when objc_registerClassPair() is called. In
+ particular, if a class is in construction, objc_getClass() will not
+ find it, the superclass will not know about it,
+ class_getSuperclass() will return Nil and another thread may
+ allocate a class pair with the same name; the conflict will only be
+ detected when the classes are registered with the runtime.
+ */
+objc_EXPORT Class
+objc_allocateClassPair (Class super_class, const char *class_name,
+ size_t extraBytes);
+
+/* Register a class pair that was created with
+ objc_allocateClassPair(). After you register a class, you can no
+ longer make changes to its instance variables, but you can start
+ creating instances of it. Do nothing if 'class_' is NULL or if it
+ is not a class allocated by objc_allocateClassPair() and still in
+ construction. */
+objc_EXPORT void
+objc_registerClassPair (Class class_);
+
+/* Dispose of a class pair created using objc_allocateClassPair().
+ Call this function if you started creating a new class with
+ objc_allocateClassPair() but then want to abort the process. You
+ should not access 'class_' after calling this method. Note that if
+ 'class_' has already been registered with the runtime via
+ objc_registerClassPair(), this function does nothing; you can only
+ dispose of class pairs that are still being constructed. Do
+ nothing if class is 'Nil' or if 'class_' is not a class being
+ constructed. */
+objc_EXPORT void
+objc_disposeClassPair (Class class_);
+
+/* Compatibility Note: The Apple/NeXT runtime has the function
+ objc_duplicateClass () but it's undocumented. The GNU runtime does
+ not have it. */
+
/** Implementation: the following functions are in sendmsg.c. */
/* Return the instance method with selector 'selector' of class
'class_', or NULL if the class (or one of its superclasses) does
not implement the method. Return NULL if class_ is Nil or selector
- is NULL. */
+ is NULL. Calling this function may trigger a call to
+ +resolveInstanceMethod:, but does not return a forwarding
+ function. */
objc_EXPORT Method class_getInstanceMethod (Class class_, SEL selector);
/* Return the class method with selector 'selector' of class 'class_',
or NULL if the class (or one of its superclasses) does not
implement the method. Return NULL if class_ is Nil or selector is
- NULL. */
+ NULL. Calling this function may trigger a call to
+ +resolveClassMethod:, but does not return a forwarding
+ function. */
objc_EXPORT Method class_getClassMethod (Class class_, SEL selector);
/* Return the IMP (pointer to the function implementing a method) for
arguments and return type before calling it. To get a class
method, you can pass the meta-class as the class_ argument (ie, use
class_getMethodImplementation (object_getClass (class_),
- selector)). Return NULL if class_ is Nil or selector is NULL. */
+ selector)). Return NULL if class_ is Nil or selector is NULL.
+ This function first looks for an existing method; if it is not
+ found, it calls +resolveClassMethod: or +resolveInstanceMethod:
+ (depending on whether a class or instance method is being looked
+ up) if it is implemented. If the method returns YES, then it tries
+ the look up again (the assumption being that +resolveClassMethod:
+ or resolveInstanceMethod: will add the method using
+ class_addMethod()). If it is still not found, it returns a
+ forwarding function. */
objc_EXPORT IMP class_getMethodImplementation (Class class_, SEL selector);
/* Compatibility Note: the Apple/NeXT runtime has the function
(object_getClass (class_), selector)). */
objc_EXPORT BOOL class_respondsToSelector (Class class_, SEL selector);
+/* Add a method to a class. Use this function to add a new method to
+ a class (potentially overriding a method with the same selector in
+ the superclass); if you want to modify an existing method, use
+ method_setImplementation() instead (or class_replaceMethod ()).
+ This method adds an instance method to 'class_'; to add a class
+ method, get the meta class first, then add the method to the meta
+ class, that is, use
+
+ class_addMethod (object_getClass (class_), selector,
+ implementation, type);
+
+ Return YES if the method was added, and NO if not. Do nothing if
+ one of the arguments is NULL. */
+objc_EXPORT BOOL class_addMethod (Class class_, SEL selector, IMP implementation,
+ const char *method_types);
+
+/* Replace a method in a class. If the class already have a method
+ with this 'selector', find it and use method_setImplementation() to
+ replace the implementation with 'implementation' (method_types is
+ ignored in that case). If the class does not already have a method
+ with this 'selector', call 'class_addMethod() to add it.
+
+ Return the previous implementation of the method, or NULL if none
+ was found. Return NULL if any of the arguments is NULL. */
+objc_EXPORT IMP class_replaceMethod (Class class_, SEL selector, IMP implementation,
+ const char *method_types);
+
/** Implementation: the following functions are in methods.c. */
objc_EXPORT BOOL class_addProtocol (Class class_, Protocol *protocol);
/* Return YES if the class 'class_' conforms to Protocol 'protocol',
- and NO if not. */
+ and NO if not. This function does not check superclasses; if you
+ want to check for superclasses (in the way that [NSObject
+ +conformsToProtocol:] does) you need to iterate over the class
+ hierarchy using class_getSuperclass(), and call
+ class_conformsToProtocol() for each of them. */
objc_EXPORT BOOL class_conformsToProtocol (Class class_, Protocol *protocol);
/* Return all the protocols that the class conforms to. The return
class. It does not include protocols adopted by superclasses. The
list is terminated by NULL. Optionally, if you pass a non-NULL
'numberOfReturnedProtocols' pointer, the unsigned int that it
- points to will be filled with the number of protocols returned. */
+ points to will be filled with the number of protocols returned.
+ This function does not return protocols that superclasses conform
+ to. */
objc_EXPORT Protocol **class_copyProtocolList (Class class_, unsigned int *numberOfReturnedProtocols);
/* Return YES if protocol 'protocol' conforms to protocol
objc_EXPORT Protocol **protocol_copyProtocolList (Protocol *protocol, unsigned int *numberOfReturnedProtocols);
-/* TODO: Add all the other functions in the API. */
+/** Implementation: the following hook is in init.c. */
+
+/* This is a hook which is called by __objc_exec_class every time a
+ class or a category is loaded into the runtime. This may e.g. help
+ a dynamic loader determine the classes that have been loaded when
+ an object file is dynamically linked in. */
+objc_EXPORT void (*_objc_load_callback)(Class _class, struct objc_category *category);
/** Implementation: the following functions are in objc-foreach.c. */
*/
+/* Compatibility Note: The Apple/NeXT runtime has the functions
+ objc_copyImageNames (), class_getImageName () and
+ objc_copyClassNamesForImage () but they are undocumented. The GNU
+ runtime does not have them at the moment. */
+
+/* Compatibility Note: The Apple/NeXT runtime has the functions
+ objc_setAssociatedObject (), objc_getAssociatedObject (),
+ objc_removeAssociatedObjects () and the objc_AssociationPolicy type
+ and related enum. The GNU runtime does not have them yet.
+ TODO: Implement them. */
+
+/* Compatibility Note: The Apple/NeXT runtime has the function
+ objc_setForwardHandler (). The GNU runtime does not have it
+ because messaging (and, in particular, forwarding) works in a
+ different (incompatible) way with the GNU runtime. If you need to
+ customize message forwarding at the Objective-C runtime level (that
+ is, if you are implementing your own "Foundation" library such as
+ GNUstep Base on top of the Objective-C runtime), in objc/message.h
+ there are hooks (that work in the framework of the GNU runtime) to
+ do so. */
+
+
/** Implementation: the following functions are in memory.c. */
/* Traditional GNU Objective-C Runtime functions that are used for
objc_EXPORT void objc_free(void *mem);
+/** Implementation: the following functions are in gc.c. */
+
+/* The GNU Objective-C Runtime has a different implementation of
+ garbage collection.
+
+ Compatibility Note: these functions are not available with the
+ Apple/NeXT runtime. */
+
+/* Mark the instance variable as inaccessible to the garbage
+ collector. */
+objc_EXPORT void class_ivar_set_gcinvisible (Class _class,
+ const char* ivarname,
+ BOOL gcInvisible);
+
+
/** Implementation: the following functions are in encoding.c. */
/* Traditional GNU Objective-C Runtime functions that are currently
/* Return the size of a variable which has the specified 'type'
encoding. */
-int objc_sizeof_type (const char *type);
+objc_EXPORT int objc_sizeof_type (const char *type);
/* Return the align of a variable which has the specified 'type'
encoding. */
-int objc_alignof_type (const char *type);
+objc_EXPORT int objc_alignof_type (const char *type);
/* Return the aligned size of a variable which has the specified
'type' encoding. The aligned size is the size rounded up to the
nearest alignment. */
-int objc_aligned_size (const char *type);
+objc_EXPORT int objc_aligned_size (const char *type);
/* Return the promoted size of a variable which has the specified
'type' encoding. This is the size rounded up to the nearest
integral of the wordsize, taken to be the size of a void *. */
-int objc_promoted_size (const char *type);
+objc_EXPORT int objc_promoted_size (const char *type);
/* The following functions are used when parsing the type encoding of
/* Skip some type qualifiers (_C_CONST, _C_IN, etc). These may
eventually precede typespecs occurring in method prototype
encodings. */
-const char *objc_skip_type_qualifiers (const char *type);
+objc_EXPORT const char *objc_skip_type_qualifiers (const char *type);
/* Skip one typespec element (_C_CLASS, _C_SEL, etc). If the typespec
is prepended by type qualifiers, these are skipped as well. */
-const char *objc_skip_typespec (const char *type);
+objc_EXPORT const char *objc_skip_typespec (const char *type);
/* Skip an offset. */
-const char *objc_skip_offset (const char *type);
+objc_EXPORT const char *objc_skip_offset (const char *type);
/* Skip an argument specification (ie, skipping a typespec, which may
include qualifiers, and an offset too). */
-const char *objc_skip_argspec (const char *type);
+objc_EXPORT const char *objc_skip_argspec (const char *type);
/* Read type qualifiers (_C_CONST, _C_IN, etc) from string 'type'
(stopping at the first non-type qualifier found) and return an
unsigned int which is the logical OR of all the corresponding flags
(_F_CONST, _F_IN etc). */
-unsigned objc_get_type_qualifiers (const char *type);
+objc_EXPORT unsigned objc_get_type_qualifiers (const char *type);
/* Note that the following functions work for very simple structures,
but get easily confused by more complicated ones (for example,
- containing vectors). A better solution is required.
-*/
+ containing vectors). A better solution is required. These
+ functions are likely to change in the next GCC release. */
/* The following three functions can be used to determine how a
structure is laid out by the compiler. For example:
unsigned int record_align;
};
-void objc_layout_structure (const char *type,
+objc_EXPORT void objc_layout_structure (const char *type,
struct objc_struct_layout *layout);
-BOOL objc_layout_structure_next_member (struct objc_struct_layout *layout);
-void objc_layout_finish_structure (struct objc_struct_layout *layout,
- unsigned int *size,
- unsigned int *align);
-void objc_layout_structure_get_info (struct objc_struct_layout *layout,
- unsigned int *offset,
- unsigned int *align,
- const char **type);
+objc_EXPORT BOOL objc_layout_structure_next_member (struct objc_struct_layout *layout);
+objc_EXPORT void objc_layout_finish_structure (struct objc_struct_layout *layout,
+ unsigned int *size,
+ unsigned int *align);
+objc_EXPORT void objc_layout_structure_get_info (struct objc_struct_layout *layout,
+ unsigned int *offset,
+ unsigned int *align,
+ const char **type);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
#endif