Small part of catching up with changes made to the objective-c language. The instancetype has been added to other objective-c implementations as a typedef alias to id in order to allow diagnosis of cases where a class is used or returned where an instance is expected.
This adds the typedef, and tests that we can parse it. It doesn't alter the diagnostics yet. tested on x86_64-darwin16, x86_64-linux-gnu applied to mainline Iain gcc/objc/ 2019-05-18 Iain Sandoe <i...@sandoe.co.uk> * objc/objc-act.h (OCTI_INSTANCE_TYPE, OCTI_INSTANCETYPE_NAME): New. (objc_global_trees): Add instance type and name. (INSTANCE_TYPEDEF_NAME): New. * objc/objc-act.c (synth_module_prologue): Build decls for objc_instancetype_type and objc_instancetype_name. gcc/testsuite/ 2019-05-18 Iain Sandoe <i...@sandoe.co.uk> * objc.dg/instancetype-0.m: New. diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 7ee3306..2173092 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -2950,12 +2950,14 @@ synth_module_prologue (void) objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id); objc_object_type = build_pointer_type (objc_object_reference); + objc_instancetype_type = build_pointer_type (objc_object_reference); objc_class_type = build_pointer_type (objc_class_reference); objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME); + objc_instancetype_name = get_identifier (INSTANCE_TYPEDEF_NAME); objc_class_name = get_identifier (CLASS_TYPEDEF_NAME); - /* Declare the 'id' and 'Class' typedefs. */ + /* Declare the 'id', 'instancetype' and 'Class' typedefs. */ type = lang_hooks.decls.pushdecl (build_decl (input_location, TYPE_DECL, objc_object_name, @@ -2964,6 +2966,12 @@ synth_module_prologue (void) type = lang_hooks.decls.pushdecl (build_decl (input_location, TYPE_DECL, + objc_instancetype_name, + objc_instancetype_type)); + TREE_NO_WARNING (type) = 1; + + type = lang_hooks.decls.pushdecl (build_decl (input_location, + TYPE_DECL, objc_class_name, objc_class_type)); TREE_NO_WARNING (type) = 1; diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h index 5794cdf..3b69043 100644 --- a/gcc/objc/objc-act.h +++ b/gcc/objc/objc-act.h @@ -313,6 +313,7 @@ enum objc_tree_index OCTI_SUPER_TYPE, OCTI_SEL_TYPE, OCTI_ID_TYPE, + OCTI_INSTANCE_TYPE, OCTI_CLS_TYPE, OCTI_NST_TYPE, OCTI_PROTO_TYPE, @@ -368,6 +369,7 @@ enum objc_tree_index OCTI_OBJ_ID, OCTI_CLS_ID, OCTI_ID_NAME, + OCTI_INSTANCETYPE_NAME, OCTI_CLASS_NAME, OCTI_CNST_STR_ID, OCTI_CNST_STR_TYPE, @@ -443,6 +445,7 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX]; #define objc_super_type objc_global_trees[OCTI_SUPER_TYPE] #define objc_selector_type objc_global_trees[OCTI_SEL_TYPE] #define objc_object_type objc_global_trees[OCTI_ID_TYPE] +#define objc_instancetype_type objc_global_trees[OCTI_INSTANCE_TYPE] #define objc_class_type objc_global_trees[OCTI_CLS_TYPE] #define objc_instance_type objc_global_trees[OCTI_NST_TYPE] #define objc_protocol_type objc_global_trees[OCTI_PROTO_TYPE] @@ -570,7 +573,8 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX]; #define objc_object_id objc_global_trees[OCTI_OBJ_ID] #define objc_class_id objc_global_trees[OCTI_CLS_ID] -#define objc_object_name objc_global_trees[OCTI_ID_NAME] +#define objc_object_name objc_global_trees[OCTI_ID_NAME] +#define objc_instancetype_name objc_global_trees[OCTI_INSTANCETYPE_NAME] #define objc_class_name objc_global_trees[OCTI_CLASS_NAME] /* Constant string classes. */ @@ -608,6 +612,7 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX]; /* Reserved tag definitions. */ #define OBJECT_TYPEDEF_NAME "id" +#define INSTANCE_TYPEDEF_NAME "instancetype" #define CLASS_TYPEDEF_NAME "Class" #define TAG_OBJECT "objc_object" diff --git a/gcc/testsuite/objc.dg/instancetype-0.m b/gcc/testsuite/objc.dg/instancetype-0.m new file mode 100644 index 0000000..60e086a --- /dev/null +++ b/gcc/testsuite/objc.dg/instancetype-0.m @@ -0,0 +1,30 @@ +/* Contributed by Iain Sandoe <i...@codesourcery.com>, December 2014. */ +/* { dg-do compile } */ + +/* Basic check of parsing instancetype. */ + +extern id class_createInstance (id, int); +extern id class_getSuperclass (id); + +@interface MyObject +{ + Class isa; +} ++ (instancetype)alloc; +- (instancetype)init; ++ (instancetype)initialize; ++ (instancetype)factoryMethodA; ++ (id)factoryMethodB; ++ (Class) class; ++ (Class) superclass; +@end + +@implementation MyObject ++ (instancetype)alloc { return class_createInstance (self, 0); } +- (instancetype)init { return self; } ++ (instancetype)initialize { return self; } ++ (instancetype)factoryMethodA { return [[[self class] alloc] init]; } ++ (id)factoryMethodB { return [[[self class] alloc] init]; } ++ (Class) class { return self; } ++ (Class) superclass { return class_getSuperclass (self); } +@end