diff options
-rw-r--r-- | gcc/objc/ChangeLog | 25 | ||||
-rw-r--r-- | gcc/objc/objc-act.c | 344 | ||||
-rw-r--r-- | gcc/objc/objc-act.h | 9 | ||||
-rw-r--r-- | gcc/objc/objc-tree.def | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/dotsyntax-10.mm | 86 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/dotsyntax-11.mm | 61 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/dotsyntax-5.mm | 78 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/dotsyntax-6.mm | 107 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/dotsyntax-7.mm | 48 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/dotsyntax-8.mm | 62 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/dotsyntax-9.mm | 77 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/dotsyntax-10.m | 86 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/dotsyntax-11.m | 61 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/dotsyntax-5.m | 78 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/dotsyntax-6.m | 107 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/dotsyntax-7.m | 48 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/dotsyntax-8.m | 62 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/property/dotsyntax-9.m | 77 |
19 files changed, 1355 insertions, 93 deletions
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 104948b..9bde682 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,28 @@ +2010-11-06 Nicola Pero <nicola.pero@meta-innovation.com> + + Fixed using the Objective-C 2.0 syntax with self and super. + * objc-act.c (OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS): New. + (maybe_make_artificial_property_decl): Added 'implementation' + argument. Use OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS when + looking up getters or setters for a class. If an implementation + is specified, search it as well for a getter or setter. + (objc_maybe_build_component_ref): Updated calls to + maybe_make_artificial_property_decl; added code to deal with + 'self' and 'super' and with methods declared locally in the + implementation. Store the getter call expression in the + PROPERTY_REF instead of throwing it away. + (objc_build_class_component_ref): Updated calls to + maybe_make_artificial_property_decl, and store the getter call + expression in PROPERTY_REF instead of throwing it away. + (lookup_method_static): Implemented + OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS option. + (objc_gimplify_property_ref): Do not build the getter method call + here; instead use the one stored in the PROPERTY_REF. If it's not + there, produce helpful error messages. + * objc-tree.def (PROPERTY_REF): Increased the number of operands + from 2 to 3. Updated comments. + * objc-act.h (PROPERTY_REF_GETTER_CALL): New. + 2010-11-06 Iain Sandoe <iains@gcc.gnu.org> PR target/44981 diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 02966a8..fd5244e 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -377,8 +377,14 @@ static const char *default_constant_string_class_name; #define TAG_GNUINIT "__objc_gnu_init" /* Flags for lookup_method_static(). */ -#define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */ -#define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */ + +/* Look for class methods. */ +#define OBJC_LOOKUP_CLASS 1 +/* Do not examine superclasses. */ +#define OBJC_LOOKUP_NO_SUPER 2 +/* Disable returning an instance method of a root class when a class + method can't be found. */ +#define OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS 4 /* The OCTI_... enumeration itself is in objc/objc-act.h. */ tree objc_global_trees[OCTI_MAX]; @@ -1085,32 +1091,58 @@ lookup_property (tree interface_type, tree property) } /* This is a subroutine of objc_maybe_build_component_ref. Search the - list of methods in the interface (and, failing that, protocol list) + list of methods in the interface (and, failing that, the local list + in the implementation, and failing that, the protocol list) provided for a 'setter' or 'getter' for 'component' with default names (ie, if 'component' is "name", then search for "name" and "setName:"). If any is found, then create an artificial property that uses them. Return NULL_TREE if 'getter' or 'setter' could not be found. */ static tree -maybe_make_artificial_property_decl (tree interface, tree protocol_list, tree component, bool is_class) +maybe_make_artificial_property_decl (tree interface, tree implementation, + tree protocol_list, tree component, bool is_class) { tree getter_name = component; tree setter_name = get_identifier (objc_build_property_setter_name (component)); tree getter = NULL_TREE; tree setter = NULL_TREE; + /* First, check the @interface and all superclasses. */ if (interface) { int flags = 0; + /* Using instance methods of the root class as accessors is most + likely unwanted and can be extremely confusing (and, most + importantly, other Objective-C 2.0 compilers do not do it). + Turn it off. */ if (is_class) - flags = OBJC_LOOKUP_CLASS; + flags = OBJC_LOOKUP_CLASS | OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS; getter = lookup_method_static (interface, getter_name, flags); setter = lookup_method_static (interface, setter_name, flags); } - /* Try the protocol_list if we didn't find anything in the interface. */ + /* Second, check the local @implementation context. */ + if (!getter && !setter) + { + if (implementation) + { + if (is_class) + { + getter = lookup_method (CLASS_CLS_METHODS (implementation), getter_name); + setter = lookup_method (CLASS_CLS_METHODS (implementation), setter_name); + } + else + { + getter = lookup_method (CLASS_NST_METHODS (implementation), getter_name); + setter = lookup_method (CLASS_NST_METHODS (implementation), setter_name); + } + } + } + + /* Try the protocol_list if we didn't find anything in the + @interface and in the @implementation. */ if (!getter && !setter) { getter = lookup_method_in_protocol_list (protocol_list, getter_name, is_class); @@ -1186,13 +1218,13 @@ objc_maybe_build_component_ref (tree object, tree property_ident) tree x = NULL_TREE; tree rtype; - /* If we are in Objective-C 1.0 mode, properties are not - available. */ + /* If we are in Objective-C 1.0 mode, dot-syntax and properties are + not available. */ if (flag_objc1_only) return NULL_TREE; - /* Try to determine quickly if 'object' is an Objective-C object or - not. If not, return. */ + /* Try to determine if 'object' is an Objective-C object or not. If + not, return. */ if (object == NULL_TREE || object == error_mark_node || (rtype = TREE_TYPE (object)) == NULL_TREE) return NULL_TREE; @@ -1201,37 +1233,118 @@ objc_maybe_build_component_ref (tree object, tree property_ident) || TREE_CODE (property_ident) != IDENTIFIER_NODE) return NULL_TREE; - /* TODO: Implement super.property. */ - - /* TODO: Carefully review the following code. */ + /* The following analysis of 'object' is similar to the one used for + the 'receiver' of a method invocation. We need to determine what + 'object' is and find the appropriate property (either declared, + or artificial) for it (in the same way as we need to find the + appropriate method prototype for a method invocation). There are + some simplifications here though: "object.property" is invalid if + "object" has a type of "id" or "Class"; it must at least have a + protocol attached to it, and "object" is never a class name as + that is done by objc_build_class_component_ref. Finally, we + don't know if this really is a dot-syntax expression, so we want + to make a quick exit if it is not; for this reason, we try to + postpone checks after determining that 'object' looks like an + Objective-C object. */ + if (objc_is_id (rtype)) { - tree rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype)) - ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype)) - : NULL_TREE); - if (rprotos) - x = lookup_property_in_protocol_list (rprotos, property_ident); + /* This is the case that the 'object' is of type 'id' or + 'Class'. */ - if (x == NULL_TREE) + /* Check if at least it is of type 'id <Protocol>' or 'Class + <Protocol>'; if so, look the property up in the + protocols. */ + if (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))) { - /* Ok, no property. Maybe it was an object.component - dot-syntax without a declared property. Look for - getter/setter methods and internally declare an artifical - property based on them if found. */ - x = maybe_make_artificial_property_decl (NULL_TREE, rprotos, - property_ident, - false); + tree rprotos = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype)); + + if (rprotos) + { + /* No point looking up declared @properties if we are + dealing with a class. Classes have no declared + properties. */ + if (!IS_CLASS (rtype)) + x = lookup_property_in_protocol_list (rprotos, property_ident); + + if (x == NULL_TREE) + { + /* Ok, no property. Maybe it was an + object.component dot-syntax without a declared + property (this is valid for classes too). Look + for getter/setter methods and internally declare + an artifical property based on them if found. */ + x = maybe_make_artificial_property_decl (NULL_TREE, + NULL_TREE, + rprotos, + property_ident, + IS_CLASS (rtype)); + } + } + } + else if (objc_method_context) + { + /* Else, if we are inside a method it could be the case of + 'super' or 'self'. */ + tree interface_type = NULL_TREE; + tree t = object; + while (TREE_CODE (t) == COMPOUND_EXPR + || TREE_CODE (t) == MODIFY_EXPR + || CONVERT_EXPR_P (t) + || TREE_CODE (t) == COMPONENT_REF) + t = TREE_OPERAND (t, 0); + + if (t == UOBJC_SUPER_decl) + interface_type = lookup_interface (CLASS_SUPER_NAME (implementation_template)); + else if (t == self_decl) + interface_type = lookup_interface (CLASS_NAME (implementation_template)); + + /* TODO: Protocols. */ + + if (interface_type) + { + if (TREE_CODE (objc_method_context) != CLASS_METHOD_DECL) + { + x = lookup_property (interface_type, property_ident); + /* TODO: Protocols. */ + } + + if (x == NULL_TREE) + { + /* Try the dot-syntax without a declared property. + If this is an access to 'self', it is possible + that they may refer to a setter/getter that is + not declared in the interface, but exists locally + in the implementation. In that case, get the + implementation context and use it. */ + tree implementation = NULL_TREE; + + if (t == self_decl) + implementation = objc_implementation_context; + + /* TODO: Protocols. */ + + x = maybe_make_artificial_property_decl + (interface_type, implementation, NULL_TREE, + property_ident, + (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)); + } + } } } else { + /* This is the case where we have more information on 'rtype'. */ tree basetype = TYPE_MAIN_VARIANT (rtype); + /* Skip the pointer - if none, it's not an Objective-C object or + class. */ if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE) basetype = TREE_TYPE (basetype); else return NULL_TREE; + /* Traverse typedefs. */ while (basetype != NULL_TREE && TREE_CODE (basetype) == RECORD_TYPE && OBJC_TYPE_NAME (basetype) @@ -1243,58 +1356,91 @@ objc_maybe_build_component_ref (tree object, tree property_ident) { tree interface_type = TYPE_OBJC_INTERFACE (basetype); tree protocol_list = TYPE_OBJC_PROTOCOL_LIST (basetype); - - x = lookup_property (interface_type, property_ident); - - if (x == NULL_TREE) - x = lookup_property_in_protocol_list (protocol_list, property_ident); - if (x == NULL_TREE) + if (interface_type + && (TREE_CODE (interface_type) == CLASS_INTERFACE_TYPE + || TREE_CODE (interface_type) == CATEGORY_INTERFACE_TYPE + || TREE_CODE (interface_type) == PROTOCOL_INTERFACE_TYPE)) { - /* Ok, no property. Try the dot-syntax without a - declared property. */ - x = maybe_make_artificial_property_decl (interface_type, protocol_list, - property_ident, false); + /* Not sure 'rtype' could ever be a class here! Just + for safety we keep the checks. */ + if (!IS_CLASS (rtype)) + { + x = lookup_property (interface_type, property_ident); + + if (x == NULL_TREE) + x = lookup_property_in_protocol_list (protocol_list, + property_ident); + } + + if (x == NULL_TREE) + { + /* Try the dot-syntax without a declared property. + If we are inside a method implementation, it is + possible that they may refer to a setter/getter + that is not declared in the interface, but exists + locally in the implementation. In that case, get + the implementation context and use it. */ + tree implementation = NULL_TREE; + + if (objc_implementation_context + && CLASS_NAME (objc_implementation_context) + == OBJC_TYPE_NAME (interface_type)) + implementation = objc_implementation_context; + + x = maybe_make_artificial_property_decl (interface_type, + implementation, + protocol_list, + property_ident, + IS_CLASS (rtype)); + } } } } + /* TODO: Fix compiling super.accessor. */ + if (x) { tree expression; - - if (TREE_DEPRECATED (x)) - warn_deprecated_use (x, NULL_TREE); - - expression = build2 (PROPERTY_REF, TREE_TYPE(x), object, x); - SET_EXPR_LOCATION (expression, input_location); - TREE_SIDE_EFFECTS (expression) = 1; + tree getter_call; /* We have an additional nasty problem here; if this PROPERTY_REF needs to become a 'getter', then the conversion from PROPERTY_REF into a getter call happens in gimplify, - after the selector table has already been generated and it is - too late to add another selector to it. To work around the - problem, we always put the selector in the table at this - stage, as if we were building the method call here. And the - easiest way to do this is precisely to build the method call, - then discard it. Note that if the PROPERTY_REF becomes a - 'setter' instead of a 'getter', then we have added a selector - too many to the selector table. This is a little - inefficient. - - TODO: This can be made more efficient; in particular we don't - need to build the whole message call, we could just work on - the selector. + after the selector table has already been generated and when + it is too late to add another selector to it. To work around + the problem, we always create the getter call at this stage, + which puts the selector in the table. Note that if the + PROPERTY_REF becomes a 'setter' instead of a 'getter', then + we have added a selector too many to the selector table. + This is a little inefficient. + + Also note that method calls to 'self' and 'super' require the + context (self_decl, UOBJS_SUPER_decl, + objc_implementation_context etc) to be built correctly; this + is yet another reason why building the call at the gimplify + stage (when this context has been lost) is not very + practical. If we build it at this stage, we know it will + always be built correctly. If the PROPERTY_HAS_NO_GETTER() (ie, it is an artificial property decl created to deal with a dotsyntax not really referring to an existing property) then do not try to build a call to the getter as there is no getter. */ - if (!PROPERTY_HAS_NO_GETTER (x)) - objc_finish_message_expr (object, - PROPERTY_GETTER_NAME (x), - NULL_TREE); + if (PROPERTY_HAS_NO_GETTER (x)) + getter_call = NULL_TREE; + else + getter_call = objc_finish_message_expr (object, + PROPERTY_GETTER_NAME (x), + NULL_TREE); + + if (TREE_DEPRECATED (x)) + warn_deprecated_use (x, NULL_TREE); + + expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call); + SET_EXPR_LOCATION (expression, input_location); + TREE_SIDE_EFFECTS (expression) = 1; return expression; } @@ -1341,26 +1487,28 @@ objc_build_class_component_ref (tree class_name, tree property_ident) return error_mark_node; } - x = maybe_make_artificial_property_decl (rtype, NULL_TREE, + x = maybe_make_artificial_property_decl (rtype, NULL_TREE, NULL_TREE, property_ident, true); if (x) { tree expression; + tree getter_call; + if (PROPERTY_HAS_NO_GETTER (x)) + getter_call = NULL_TREE; + else + getter_call = objc_finish_message_expr (object, + PROPERTY_GETTER_NAME (x), + NULL_TREE); if (TREE_DEPRECATED (x)) warn_deprecated_use (x, NULL_TREE); - expression = build2 (PROPERTY_REF, TREE_TYPE(x), object, x); + expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call); SET_EXPR_LOCATION (expression, input_location); TREE_SIDE_EFFECTS (expression) = 1; - /* See above for why we do this. */ - if (!PROPERTY_HAS_NO_GETTER (x)) - objc_finish_message_expr (object, - PROPERTY_GETTER_NAME (x), - NULL_TREE); - + return expression; } else @@ -7957,13 +8105,16 @@ lookup_method (tree mchain, tree method) return NULL_TREE; } -/* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method - in INTERFACE, along with any categories and protocols attached thereto. - If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS, - recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is - set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could - be found in INTERFACE or any of its superclasses, look for an _instance_ - method of the same name in the root class as a last resort. +/* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance + method in INTERFACE, along with any categories and protocols + attached thereto. If method is not found, and the + OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS, recursively examine the + INTERFACE's superclass. If OBJC_LOOKUP_CLASS is set, + OBJC_LOOKUP_NO_SUPER is clear, and no suitable class method could + be found in INTERFACE or any of its superclasses, look for an + _instance_ method of the same name in the root class as a last + resort. This behaviour can be turned off by using + OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS. If a suitable method cannot be found, return NULL_TREE. */ @@ -7974,6 +8125,7 @@ lookup_method_static (tree interface, tree ident, int flags) tree inter = interface; int is_class = (flags & OBJC_LOOKUP_CLASS); int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER); + int no_instance_methods_of_root_class = (flags & OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS); while (inter) { @@ -8020,11 +8172,18 @@ lookup_method_static (tree interface, tree ident, int flags) } while (inter); - /* If no class (factory) method was found, check if an _instance_ - method of the same name exists in the root class. This is what - the Objective-C runtime will do. If an instance method was not - found, return 0. */ - return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE; + if (is_class && !no_instance_methods_of_root_class) + { + /* If no class (factory) method was found, check if an _instance_ + method of the same name exists in the root class. This is what + the Objective-C runtime will do. */ + return lookup_method_static (root_inter, ident, 0); + } + else + { + /* If an instance method was not found, return 0. */ + return NULL_TREE; + } } /* Add the method to the hash list if it doesn't contain an identical @@ -12038,15 +12197,24 @@ objc_rewrite_function_call (tree function, tree first_param) static void objc_gimplify_property_ref (tree *expr_p) { - tree object_expression = PROPERTY_REF_OBJECT (*expr_p); - tree property_decl = PROPERTY_REF_PROPERTY_DECL (*expr_p); - tree call_exp, getter; - - /* TODO: Implement super.property. */ + tree getter = PROPERTY_REF_GETTER_CALL (*expr_p); + tree call_exp; + + if (getter == NULL_TREE) + { + tree property_decl = PROPERTY_REF_PROPERTY_DECL (*expr_p); + /* This can happen if DECL_ARTIFICIAL (*expr_p), but + should be impossible for real properties, which always + have a getter. */ + error_at (EXPR_LOCATION (*expr_p), "no %qs getter found", + IDENTIFIER_POINTER (PROPERTY_NAME (property_decl))); + /* Try to recover from the error to prevent an ICE. We take + zero and cast it to the type of the property. */ + *expr_p = convert (TREE_TYPE (property_decl), + integer_zero_node); + return; + } - getter = objc_finish_message_expr (object_expression, - PROPERTY_GETTER_NAME (property_decl), - NULL_TREE); call_exp = getter; #ifdef OBJCPLUS /* In C++, a getter which returns an aggregate value results in a diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h index 9478d72..9a9cacd 100644 --- a/gcc/objc/objc-act.h +++ b/gcc/objc/objc-act.h @@ -131,6 +131,15 @@ typedef enum objc_property_assign_semantics { declared property. */ #define PROPERTY_REF_PROPERTY_DECL(NODE) TREE_OPERAND (PROPERTY_REF_CHECK (NODE), 1) +/* PROPERTY_REF_GETTER_CALL is the getter call expression, ready to + use at gimplify time if needed. Generating the getter call + requires modifying the selector table, and, in the case of + self/super, requires the context to be generated correctly. The + gimplify stage is too late to do these things, so we generate the + getter call earlier instead, and keep it here in case we need to + use it. */ +#define PROPERTY_REF_GETTER_CALL(NODE) TREE_OPERAND (PROPERTY_REF_CHECK (NODE), 2) + /* CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE, CATEGORY_INTERFACE_TYPE, CATEGORY_IMPLEMENTATION_TYPE, diff --git a/gcc/objc/objc-tree.def b/gcc/objc/objc-tree.def index 7316675..e33fc78 100644 --- a/gcc/objc/objc-tree.def +++ b/gcc/objc/objc-tree.def @@ -44,9 +44,11 @@ DEFTREECODE (CLASS_REFERENCE_EXPR, "class_reference_expr", tcc_expression, 1) where 'object' is an Objective-C object and 'property' is an Objective-C property. Operand 0 is the object (the tree representing the expression), and Operand 1 is the property (the - PROPERTY_DECL). A PROPERTY_REF tree needs to be transformed into - 'setter' and 'getter' calls at some point; at the moment this - happens in two places: + PROPERTY_DECL). Operand 2 is the 'getter' call, ready to be used; + we pregenerate it because it is hard to generate it properly later + on. A PROPERTY_REF tree needs to be transformed into 'setter' and + 'getter' calls at some point; at the moment this happens in two + places: * if we detect that a modify expression is being applied to a PROPERTY_REF, then we transform that into a 'getter' call (this @@ -54,13 +56,15 @@ DEFTREECODE (CLASS_REFERENCE_EXPR, "class_reference_expr", tcc_expression, 1) * else, it will remain as a PROPERTY_REF until we get to gimplification; at that point, we convert each PROPERTY_REF into - a 'getter' call during ObjC/ObjC++ gimplify. + a 'getter' call during ObjC/ObjC++ gimplify. At that point, it + is quite hard to build a 'getter' call, but we have already built + it and we just need to swap Operand 2 in. Please note that when the Objective-C 2.0 "dot-syntax" 'object.component' is encountered, where 'component' is not a property but there are valid setter/getter methods for it, an artificial PROPERTY_DECL is generated and used in the PROPERTY_REF. */ -DEFTREECODE (PROPERTY_REF, "property_ref", tcc_expression, 2) +DEFTREECODE (PROPERTY_REF, "property_ref", tcc_expression, 3) /* Local variables: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c9a0dc6..fc8fc74 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2010-11-06 Nicola Pero <nicola.pero@meta-innovation.com> + + Fixed using the Objective-C 2.0 dot-syntax with self and super. + * objc.dg/property/dotsyntax-5.m: New. + * objc.dg/property/dotsyntax-6.m: New. + * objc.dg/property/dotsyntax-7.m: New. + * objc.dg/property/dotsyntax-8.m: New. + * objc.dg/property/dotsyntax-9.m: New. + * objc.dg/property/dotsyntax-10.m: New. + * objc.dg/property/dotsyntax-11.m: New. + * obj-c++.dg/property/dotsyntax-5.mm: New. + * obj-c++.dg/property/dotsyntax-6.mm: New. + * obj-c++.dg/property/dotsyntax-7.mm: New. + * obj-c++.dg/property/dotsyntax-8.mm: New. + * obj-c++.dg/property/dotsyntax-9.mm: New. + * obj-c++.dg/property/dotsyntax-10.mm: New. + * obj-c++.dg/property/dotsyntax-11.mm: New. + 2010-11-06 Iain Sandoe <iains@gcc.gnu.org> * obj-c++.dg/encode-3.mm: Provide a different string check for the diff --git a/gcc/testsuite/obj-c++.dg/property/dotsyntax-10.mm b/gcc/testsuite/obj-c++.dg/property/dotsyntax-10.mm new file mode 100644 index 0000000..433595f --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/dotsyntax-10.mm @@ -0,0 +1,86 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test dot-syntax with 'super'. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +static int c; + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +- (int) count; +- (void) setCount: (int)count; ++ (int) classCount; ++ (void) setClassCount: (int)count; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} ++ (int) classCount +{ + return c; +} ++ (void) setClassCount: (int)count +{ + c = count; +} +@end + +@interface MySubClass : MyRootClass ++ (int) testMe; +- (int) testMe; +@end + +@implementation MySubClass +- (int) testMe +{ + super.count = 400; + if (super.count != 400) + abort (); + + return super.count; +} ++ (int) testMe +{ + super.classCount = 4000; + if (super.classCount != 4000) + abort (); + + return super.classCount; +} +@end + +int main (void) +{ + MySubClass *object = [[MySubClass alloc] init]; + + if ([object testMe] != 400) + abort (); + + if ([MySubClass testMe] != 4000) + abort (); + + return 0; +} + + diff --git a/gcc/testsuite/obj-c++.dg/property/dotsyntax-11.mm b/gcc/testsuite/obj-c++.dg/property/dotsyntax-11.mm new file mode 100644 index 0000000..6c9d924 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/dotsyntax-11.mm @@ -0,0 +1,61 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do compile } */ + +/* Test the error reporting for the dot-syntax in the scenario where + we have a setter, but not a getter, yet a getter is requested. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +static int c; + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +- (void) setCount: (int)count; ++ (void) setClassCount: (int)count; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (void) setCount: (int)count +{ + a = count; +} ++ (void) setClassCount: (int)count +{ + c = count; +} +@end + +@interface MySubClass : MyRootClass ++ (int) testMe; +- (int) testMe; +@end + +@implementation MySubClass +- (int) testMe +{ + super.count = 400; + if (super.count != 400) /* { dg-error "no .count. getter found" } */ + abort (); + + return super.count; /* { dg-error "no .count. getter found" } */ +} ++ (int) testMe +{ + super.classCount = 4000; + if (super.classCount != 4000) /* { dg-error "no .classCount. getter found" } */ + abort (); + + return super.classCount; /* { dg-error "no .classCount. getter found" } */ +} +@end diff --git a/gcc/testsuite/obj-c++.dg/property/dotsyntax-5.mm b/gcc/testsuite/obj-c++.dg/property/dotsyntax-5.mm new file mode 100644 index 0000000..06e1130 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/dotsyntax-5.mm @@ -0,0 +1,78 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test the 'dot syntax' with self, both in instance and class methods. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +static int c; + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +- (int) count; +- (void) setCount: (int)count; ++ (int) classCount; ++ (void) setClassCount: (int)count; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} ++ (int) classCount +{ + return c; +} ++ (void) setClassCount: (int)count +{ + c = count; +} +- (int) testMe +{ + self.count = 400; + if (self.count != 400) + abort (); + + return self.count; +} ++ (int) testMe +{ + self.classCount = 4000; + if (self.classCount != 4000) + abort (); + + return self.classCount; +} +@end + +int main (void) +{ + MyRootClass *object = [[MyRootClass alloc] init]; + + if ([object testMe] != 400) + abort (); + + if ([MyRootClass testMe] != 4000) + abort (); + + return 0; +} + + diff --git a/gcc/testsuite/obj-c++.dg/property/dotsyntax-6.mm b/gcc/testsuite/obj-c++.dg/property/dotsyntax-6.mm new file mode 100644 index 0000000..cc8c567c --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/dotsyntax-6.mm @@ -0,0 +1,107 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test nested 'dot syntax' (xxx.yyy.zzz or [xxx yyy].zzz). */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@class MyRootClass; + +static int c; +static MyRootClass *shared_root = nil; + +@interface MyRootClass +{ + Class isa; + int a; + int b; + MyRootClass *next; +} +@property int b; +@property (assign) MyRootClass *next; ++ (id) initialize; ++ (MyRootClass *)sharedInstance; ++ (id) alloc; +- (id) init; +- (MyRootClass *)same; +- (int) count; +- (void) setCount: (int)count; +@end + +@implementation MyRootClass +@synthesize b; +@synthesize next; ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } ++ (MyRootClass *)sharedInstance +{ + if (!shared_root) + shared_root = [[self alloc] init]; + + return shared_root; +} +- (MyRootClass *)same +{ + return self; +} +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} +@end + +int main (void) +{ + MyRootClass *object = [[MyRootClass alloc] init]; + + /* Test ClassName.accessor.accessor. */ + MyRootClass.sharedInstance.count = 500; + if (MyRootClass.sharedInstance.count != 500) + abort (); + + /* Test object.accessor.accessor. */ + object.same.count = 1000; + if (object.same.count != 1000) + abort (); + + /* Test object.accessor.property. */ + object.same.next = object; + if (object.same.next != object) + abort (); + + /* Test lots of nesting. */ + if (object.next.next.same.same.next.next.same != object) + abort (); + + /* Test more nesting. */ + MyRootClass.sharedInstance.next = object; + MyRootClass.sharedInstance.next.next.next.next.next.count = 2000; + if (MyRootClass.sharedInstance.next.next.next.next.next.count != 2000) + abort (); + + /* Test more nesting. */ + MyRootClass.sharedInstance.same.same.same.same.same.count = 3000; + if (MyRootClass.sharedInstance.same.same.same.same.same.count != 3000) + abort (); + + /* Test [object method].property. */ + [MyRootClass sharedInstance].count = 5000; + if ([MyRootClass sharedInstance].count != 5000) + abort (); + + /* Just a final check. */ + if (shared_root.count != 5000) + abort (); + + return 0; +} + + diff --git a/gcc/testsuite/obj-c++.dg/property/dotsyntax-7.mm b/gcc/testsuite/obj-c++.dg/property/dotsyntax-7.mm new file mode 100644 index 0000000..15c1725 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/dotsyntax-7.mm @@ -0,0 +1,48 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test dot syntax of a casted expression. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +- (int) count; +- (void) setCount: (int)count; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} +@end + +int main (void) +{ + id object = [[MyRootClass alloc] init]; + + ((MyRootClass *)object).count = 200; + if (((MyRootClass *)object).count != 200) + abort (); + + return 0; +} + + diff --git a/gcc/testsuite/obj-c++.dg/property/dotsyntax-8.mm b/gcc/testsuite/obj-c++.dg/property/dotsyntax-8.mm new file mode 100644 index 0000000..35dfda4 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/dotsyntax-8.mm @@ -0,0 +1,62 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test the 'dot syntax' with typedefs. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +static int c; + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +- (int) count; +- (void) setCount: (int)count; ++ (int) classCount; ++ (void) setClassCount: (int)count; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} ++ (int) classCount +{ + return c; +} ++ (void) setClassCount: (int)count +{ + c = count; +} +@end + +typedef MyRootClass MyType; + +int main (void) +{ + MyType *object = [[MyRootClass alloc] init]; + + object.count = 1974; + if (object.count != 1974) + abort (); + + return 0; +} + + diff --git a/gcc/testsuite/obj-c++.dg/property/dotsyntax-9.mm b/gcc/testsuite/obj-c++.dg/property/dotsyntax-9.mm new file mode 100644 index 0000000..61a5c0e --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/dotsyntax-9.mm @@ -0,0 +1,77 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test that setter/getters for dot-syntax are properly found even if + not declared in the @interface, but available in the local + @implementation before the current line (ie, [object name] can be + compiled in that case, so object.name should be compiled too). */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +static int c; + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} ++ (int) classCount +{ + return c; +} ++ (void) setClassCount: (int)count +{ + c = count; +} +- (int) testMe +{ + self.count = 400; + if (self.count != 400) + abort (); + + return self.count; +} ++ (int) testMe +{ + self.classCount = 4000; + if (self.classCount != 4000) + abort (); + + return self.classCount; +} +@end + +int main (void) +{ + MyRootClass *object = [[MyRootClass alloc] init]; + + if ([object testMe] != 400) + abort (); + + if ([MyRootClass testMe] != 4000) + abort (); + + return 0; +} + + diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-10.m b/gcc/testsuite/objc.dg/property/dotsyntax-10.m new file mode 100644 index 0000000..433595f --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dotsyntax-10.m @@ -0,0 +1,86 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test dot-syntax with 'super'. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +static int c; + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +- (int) count; +- (void) setCount: (int)count; ++ (int) classCount; ++ (void) setClassCount: (int)count; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} ++ (int) classCount +{ + return c; +} ++ (void) setClassCount: (int)count +{ + c = count; +} +@end + +@interface MySubClass : MyRootClass ++ (int) testMe; +- (int) testMe; +@end + +@implementation MySubClass +- (int) testMe +{ + super.count = 400; + if (super.count != 400) + abort (); + + return super.count; +} ++ (int) testMe +{ + super.classCount = 4000; + if (super.classCount != 4000) + abort (); + + return super.classCount; +} +@end + +int main (void) +{ + MySubClass *object = [[MySubClass alloc] init]; + + if ([object testMe] != 400) + abort (); + + if ([MySubClass testMe] != 4000) + abort (); + + return 0; +} + + diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-11.m b/gcc/testsuite/objc.dg/property/dotsyntax-11.m new file mode 100644 index 0000000..6c9d924 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dotsyntax-11.m @@ -0,0 +1,61 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do compile } */ + +/* Test the error reporting for the dot-syntax in the scenario where + we have a setter, but not a getter, yet a getter is requested. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +static int c; + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +- (void) setCount: (int)count; ++ (void) setClassCount: (int)count; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (void) setCount: (int)count +{ + a = count; +} ++ (void) setClassCount: (int)count +{ + c = count; +} +@end + +@interface MySubClass : MyRootClass ++ (int) testMe; +- (int) testMe; +@end + +@implementation MySubClass +- (int) testMe +{ + super.count = 400; + if (super.count != 400) /* { dg-error "no .count. getter found" } */ + abort (); + + return super.count; /* { dg-error "no .count. getter found" } */ +} ++ (int) testMe +{ + super.classCount = 4000; + if (super.classCount != 4000) /* { dg-error "no .classCount. getter found" } */ + abort (); + + return super.classCount; /* { dg-error "no .classCount. getter found" } */ +} +@end diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-5.m b/gcc/testsuite/objc.dg/property/dotsyntax-5.m new file mode 100644 index 0000000..06e1130 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dotsyntax-5.m @@ -0,0 +1,78 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test the 'dot syntax' with self, both in instance and class methods. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +static int c; + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +- (int) count; +- (void) setCount: (int)count; ++ (int) classCount; ++ (void) setClassCount: (int)count; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} ++ (int) classCount +{ + return c; +} ++ (void) setClassCount: (int)count +{ + c = count; +} +- (int) testMe +{ + self.count = 400; + if (self.count != 400) + abort (); + + return self.count; +} ++ (int) testMe +{ + self.classCount = 4000; + if (self.classCount != 4000) + abort (); + + return self.classCount; +} +@end + +int main (void) +{ + MyRootClass *object = [[MyRootClass alloc] init]; + + if ([object testMe] != 400) + abort (); + + if ([MyRootClass testMe] != 4000) + abort (); + + return 0; +} + + diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-6.m b/gcc/testsuite/objc.dg/property/dotsyntax-6.m new file mode 100644 index 0000000..cc8c567c --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dotsyntax-6.m @@ -0,0 +1,107 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test nested 'dot syntax' (xxx.yyy.zzz or [xxx yyy].zzz). */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@class MyRootClass; + +static int c; +static MyRootClass *shared_root = nil; + +@interface MyRootClass +{ + Class isa; + int a; + int b; + MyRootClass *next; +} +@property int b; +@property (assign) MyRootClass *next; ++ (id) initialize; ++ (MyRootClass *)sharedInstance; ++ (id) alloc; +- (id) init; +- (MyRootClass *)same; +- (int) count; +- (void) setCount: (int)count; +@end + +@implementation MyRootClass +@synthesize b; +@synthesize next; ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } ++ (MyRootClass *)sharedInstance +{ + if (!shared_root) + shared_root = [[self alloc] init]; + + return shared_root; +} +- (MyRootClass *)same +{ + return self; +} +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} +@end + +int main (void) +{ + MyRootClass *object = [[MyRootClass alloc] init]; + + /* Test ClassName.accessor.accessor. */ + MyRootClass.sharedInstance.count = 500; + if (MyRootClass.sharedInstance.count != 500) + abort (); + + /* Test object.accessor.accessor. */ + object.same.count = 1000; + if (object.same.count != 1000) + abort (); + + /* Test object.accessor.property. */ + object.same.next = object; + if (object.same.next != object) + abort (); + + /* Test lots of nesting. */ + if (object.next.next.same.same.next.next.same != object) + abort (); + + /* Test more nesting. */ + MyRootClass.sharedInstance.next = object; + MyRootClass.sharedInstance.next.next.next.next.next.count = 2000; + if (MyRootClass.sharedInstance.next.next.next.next.next.count != 2000) + abort (); + + /* Test more nesting. */ + MyRootClass.sharedInstance.same.same.same.same.same.count = 3000; + if (MyRootClass.sharedInstance.same.same.same.same.same.count != 3000) + abort (); + + /* Test [object method].property. */ + [MyRootClass sharedInstance].count = 5000; + if ([MyRootClass sharedInstance].count != 5000) + abort (); + + /* Just a final check. */ + if (shared_root.count != 5000) + abort (); + + return 0; +} + + diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-7.m b/gcc/testsuite/objc.dg/property/dotsyntax-7.m new file mode 100644 index 0000000..15c1725 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dotsyntax-7.m @@ -0,0 +1,48 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test dot syntax of a casted expression. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +- (int) count; +- (void) setCount: (int)count; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} +@end + +int main (void) +{ + id object = [[MyRootClass alloc] init]; + + ((MyRootClass *)object).count = 200; + if (((MyRootClass *)object).count != 200) + abort (); + + return 0; +} + + diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-8.m b/gcc/testsuite/objc.dg/property/dotsyntax-8.m new file mode 100644 index 0000000..35dfda4 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dotsyntax-8.m @@ -0,0 +1,62 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test the 'dot syntax' with typedefs. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +static int c; + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +- (int) count; +- (void) setCount: (int)count; ++ (int) classCount; ++ (void) setClassCount: (int)count; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} ++ (int) classCount +{ + return c; +} ++ (void) setClassCount: (int)count +{ + c = count; +} +@end + +typedef MyRootClass MyType; + +int main (void) +{ + MyType *object = [[MyRootClass alloc] init]; + + object.count = 1974; + if (object.count != 1974) + abort (); + + return 0; +} + + diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-9.m b/gcc/testsuite/objc.dg/property/dotsyntax-9.m new file mode 100644 index 0000000..61a5c0e --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dotsyntax-9.m @@ -0,0 +1,77 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test that setter/getters for dot-syntax are properly found even if + not declared in the @interface, but available in the local + @implementation before the current line (ie, [object name] can be + compiled in that case, so object.name should be compiled too). */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +static int c; + +@interface MyRootClass +{ + Class isa; + int a; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +- (int) count +{ + return a; +} +- (void) setCount: (int)count +{ + a = count; +} ++ (int) classCount +{ + return c; +} ++ (void) setClassCount: (int)count +{ + c = count; +} +- (int) testMe +{ + self.count = 400; + if (self.count != 400) + abort (); + + return self.count; +} ++ (int) testMe +{ + self.classCount = 4000; + if (self.classCount != 4000) + abort (); + + return self.classCount; +} +@end + +int main (void) +{ + MyRootClass *object = [[MyRootClass alloc] init]; + + if ([object testMe] != 400) + abort (); + + if ([MyRootClass testMe] != 4000) + abort (); + + return 0; +} + + |