From: Fariborz Jahanian Date: Wed, 18 Sep 2013 20:35:47 +0000 (+0000) Subject: ObjectiveC migrator: For consistency, also infer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a346eb1188419d3f1698092edfbd66890b74163c;p=clang ObjectiveC migrator: For consistency, also infer 'instancetype' for known family of methods with related result type; such as 'init' methods. // rdar://14987948 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190956 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 7681320557..01b8e1f361 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -586,7 +586,8 @@ enum ObjCInstanceTypeFamily { OIT_None, OIT_Array, OIT_Dictionary, - OIT_Singleton + OIT_Singleton, + OIT_Init }; /// \brief Smart pointer class that efficiently represents Objective-C method diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index 08444442c7..cffa625d3b 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -657,11 +657,6 @@ static void ReplaceWithInstancetype(const ObjCMigrateASTConsumer &ASTC, void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx, ObjCContainerDecl *CDecl, ObjCMethodDecl *OM) { - // bail out early and do not suggest 'instancetype' when the method already - // has a related result type, - if (OM->hasRelatedResultType()) - return; - ObjCInstanceTypeFamily OIT_Family = Selector::getInstTypeMethodFamily(OM->getSelector()); @@ -679,6 +674,10 @@ void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx, case OIT_Singleton: migrateFactoryMethod(Ctx, CDecl, OM, OIT_Singleton); return; + case OIT_Init: + if (OM->getResultType()->isObjCIdType()) + ReplaceWithInstancetype(*this, OM); + return; } if (!OM->getResultType()->isObjCIdType()) return; diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp index 5102f7cfd3..a3eafe2b59 100644 --- a/lib/Basic/IdentifierTable.cpp +++ b/lib/Basic/IdentifierTable.cpp @@ -471,6 +471,8 @@ ObjCInstanceTypeFamily Selector::getInstTypeMethodFamily(Selector sel) { if (startsWithWord(name, "shared") || startsWithWord(name, "standard")) return OIT_Singleton; + case 'i': + if (startsWithWord(name, "init")) return OIT_Init; default: break; } diff --git a/test/ARCMT/objcmt-arc-cf-annotations.m.result b/test/ARCMT/objcmt-arc-cf-annotations.m.result index 43537c85d8..63e39abb96 100644 --- a/test/ARCMT/objcmt-arc-cf-annotations.m.result +++ b/test/ARCMT/objcmt-arc-cf-annotations.m.result @@ -144,7 +144,7 @@ typedef struct _NSZone NSZone; - (oneway void)release; - (id)autorelease; - (NSString *)description; -- (id)init; +- (instancetype)init; @end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @@ -174,18 +174,18 @@ NSFastEnumerationState; @end @interface NSNumber : NSValue - (char)charValue; -- (id)initWithInt:(int)value; +- (instancetype)initWithInt:(int)value; + (NSNumber *)numberWithInt:(int)value; @end @class NSString; @interface NSArray : NSObject - (NSUInteger)count; -- (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt; +- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt; + (instancetype)arrayWithObject:(id)anObject; + (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; + (instancetype)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); -- (id)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); -- (id)initWithArray:(NSArray *)array; +- (instancetype)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); +- (instancetype)initWithArray:(NSArray *)array; @end @interface NSArray (NSArrayCreation) + (instancetype)array; @end @interface NSAutoreleasePool : NSObject { } @@ -198,7 +198,7 @@ typedef double NSTimeInterval; - (NSUInteger)length; - (NSString *)stringByAppendingString:(NSString *)aString; - ( const char *)UTF8String; -- (id)initWithUTF8String:(const char *)nullTerminatedCString; +- (instancetype)initWithUTF8String:(const char *)nullTerminatedCString; + (instancetype)stringWithUTF8String:(const char *)nullTerminatedCString; @end @class NSString, NSURL, NSError; @interface NSData : NSObject - (NSUInteger)length; @@ -254,7 +254,7 @@ extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ) CF_RETURNS_RETAINED; extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ) CF_RETURNS_RETAINED; extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ) CF_RETURNS_RETAINED; -@interface NSTask : NSObject - (id)init; +@interface NSTask : NSObject - (instancetype)init; @end typedef struct CGColorSpace *CGColorSpaceRef; typedef struct CGImage *CGImageRef; typedef struct CGLayer *CGLayerRef; @@ -840,16 +840,16 @@ typedef CFTypeRef OtherRef; @interface RDar6320065 : NSObject { NSString *_foo; } -- (id)initReturningNewClass; +- (instancetype)initReturningNewClass; - (id)_initReturningNewClassBad; -- (id)initReturningNewClassBad2; +- (instancetype)initReturningNewClassBad2; @end @interface RDar6320065Subclass : RDar6320065 @end @implementation RDar6320065 -- (id)initReturningNewClass { +- (instancetype)initReturningNewClass { [self release]; self = [[RDar6320065Subclass alloc] init]; // no-warning return self; @@ -859,7 +859,7 @@ typedef CFTypeRef OtherRef; [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}} return self; } -- (id)initReturningNewClassBad2 { +- (instancetype)initReturningNewClassBad2 { [self release]; self = [[RDar6320065Subclass alloc] init]; return [self autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} @@ -1778,11 +1778,11 @@ void rdar9658496() { // Support annotations with method families. @interface RDar10824732 : NSObject -- (id)initWithObj:(id CF_CONSUMED)obj; +- (instancetype)initWithObj:(id CF_CONSUMED)obj; @end @implementation RDar10824732 -- (id)initWithObj:(id)obj { +- (instancetype)initWithObj:(id)obj { [obj release]; return [super init]; } @@ -2050,12 +2050,12 @@ void testCustomReturnsNotRetained() { // Don't print variables which are out of the current scope. //===----------------------------------------------------------------------===// @interface MyObj12706177 : NSObject --(id)initX; +-(instancetype)initX; +(void)test12706177; @end static int Cond; @implementation MyObj12706177 --(id)initX { +-(instancetype)initX { if (Cond) return 0; self = [super init]; diff --git a/test/ARCMT/objcmt-instancetype.m.result b/test/ARCMT/objcmt-instancetype.m.result index 6303232ba6..7220696087 100644 --- a/test/ARCMT/objcmt-instancetype.m.result +++ b/test/ARCMT/objcmt-instancetype.m.result @@ -12,7 +12,7 @@ typedef signed char BOOL; @interface NSString : NSObject + (instancetype)stringWithString:(NSString *)string; -- (id)initWithString:(NSString *)aString; +- (instancetype)initWithString:(NSString *)aString; @end @interface NSArray : NSObject @@ -27,9 +27,9 @@ typedef signed char BOOL; + (instancetype)arrayWithObjects:(id)firstObj, ...; + (instancetype) arrayWithArray:(NSArray *)array; -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; +- (instancetype)initWithObjects:(const id [])objects count:(unsigned long)cnt; +- (instancetype)initWithObjects:(id)firstObj, ...; +- (instancetype)initWithArray:(NSArray *)array; - (id)objectAtIndex:(unsigned long)index; @end @@ -51,10 +51,10 @@ typedef signed char BOOL; + (instancetype)dictionaryWithDictionary:(NSDictionary *)dict; + (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; +- (instancetype)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +- (instancetype)initWithObjectsAndKeys:(id)firstObject, ...; +- (instancetype)initWithDictionary:(NSDictionary *)otherDictionary; +- (instancetype)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - (id)objectForKey:(id)aKey; @end