From: Fariborz Jahanian Date: Wed, 4 Sep 2013 22:49:19 +0000 (+0000) Subject: ObjectiveC migrator: start introducing NS_XXX annotations X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4afe57965e19d9c9ba8070ac9901ed8a20e20fce;p=clang ObjectiveC migrator: start introducing NS_XXX annotations to Method/functions returning ObjC objects. wip. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190005 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index 86312b6e0c..251cbaf221 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -940,14 +940,23 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, if (!ResultAnnotated) { RetEffect Ret = CE.getReturnValue(); const char *AnnotationString = 0; - if (Ret.getObjKind() == RetEffect::CF && Ret.isOwned()) { - if (Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition()) + if (Ret.getObjKind() == RetEffect::CF) { + if (Ret.isOwned() && + Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition()) AnnotationString = " CF_RETURNS_RETAINED"; - } - else if (Ret.getObjKind() == RetEffect::CF && Ret.notOwned()) { - if (Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition()) + else if (Ret.notOwned() && + Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition()) AnnotationString = " CF_RETURNS_NOT_RETAINED"; } + else if (Ret.getObjKind() == RetEffect::ObjC) { + if (Ret.isOwned() && + Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition()) + AnnotationString = " NS_RETURNS_RETAINED"; + else if (Ret.notOwned() && + Ctx.Idents.get("NS_RETURNS_NOT_RETAINED").hasMacroDefinition()) + AnnotationString = " NS_RETURNS_NOT_RETAINED"; + } + if (AnnotationString) { edit::Commit commit(*Editor); commit.insertAfterToken(FuncDecl->getLocEnd(), AnnotationString); @@ -966,6 +975,12 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, commit.insertBefore(pd->getLocation(), "CF_CONSUMED "); Editor->commit(commit); } + else if (AE == DecRefMsg && !pd->getAttr() && + Ctx.Idents.get("NS_CONSUMED").hasMacroDefinition()) { + edit::Commit commit(*Editor); + commit.insertBefore(pd->getLocation(), "NS_CONSUMED "); + Editor->commit(commit); + } } } @@ -979,7 +994,9 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND CallEffects CE = CallEffects::getEffect(FuncDecl); bool FuncIsReturnAnnotated = (FuncDecl->getAttr() || - FuncDecl->getAttr()); + FuncDecl->getAttr() || + FuncDecl->getAttr() || + FuncDecl->getAttr()); // Trivial case of when funciton is annotated and has no argument. if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0) @@ -1046,14 +1063,23 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, if (!ResultAnnotated) { RetEffect Ret = CE.getReturnValue(); const char *AnnotationString = 0; - if (Ret.getObjKind() == RetEffect::CF && Ret.isOwned()) { - if (Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition()) + if (Ret.getObjKind() == RetEffect::CF) { + if (Ret.isOwned() && + Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition()) AnnotationString = " CF_RETURNS_RETAINED"; - } - else if (Ret.getObjKind() == RetEffect::CF && Ret.notOwned()) { - if (Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition()) + else if (Ret.notOwned() && + Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition()) AnnotationString = " CF_RETURNS_NOT_RETAINED"; } + else if (Ret.getObjKind() == RetEffect::ObjC) { + if (Ret.isOwned() && + Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition()) + AnnotationString = " NS_RETURNS_RETAINED"; + else if (Ret.notOwned() && + Ctx.Idents.get("NS_RETURNS_NOT_RETAINED").hasMacroDefinition()) + AnnotationString = " NS_RETURNS_NOT_RETAINED"; + } + if (AnnotationString) { edit::Commit commit(*Editor); commit.insertBefore(MethodDecl->getLocEnd(), AnnotationString); @@ -1078,12 +1104,14 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, void ObjCMigrateASTConsumer::migrateAddMethodAnnotation( ASTContext &Ctx, const ObjCMethodDecl *MethodDecl) { - if (MethodDecl->hasBody()) + if (MethodDecl->hasBody() || MethodDecl->isImplicit()) return; CallEffects CE = CallEffects::getEffect(MethodDecl); bool MethodIsReturnAnnotated = (MethodDecl->getAttr() || - MethodDecl->getAttr()); + MethodDecl->getAttr() || + MethodDecl->getAttr() || + MethodDecl->getAttr()); // Trivial case of when funciton is annotated and has no argument. if (MethodIsReturnAnnotated && @@ -1092,7 +1120,9 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation( if (!MethodIsReturnAnnotated) { RetEffect Ret = CE.getReturnValue(); - if (Ret.getObjKind() == RetEffect::CF && (Ret.isOwned() || Ret.notOwned())) { + if ((Ret.getObjKind() == RetEffect::CF || + Ret.getObjKind() == RetEffect::ObjC) && + (Ret.isOwned() || Ret.notOwned())) { AddCFAnnotations(Ctx, CE, MethodDecl, false); return; } diff --git a/test/ARCMT/objcmt-arc-cf-annotations.m.result b/test/ARCMT/objcmt-arc-cf-annotations.m.result index e55b0b3712..8478ff51c0 100644 --- a/test/ARCMT/objcmt-arc-cf-annotations.m.result +++ b/test/ARCMT/objcmt-arc-cf-annotations.m.result @@ -175,15 +175,15 @@ NSFastEnumerationState; @interface NSNumber : NSValue - (char)charValue; - (id)initWithInt:(int)value; -+ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithInt:(int)value NS_RETURNS_NOT_RETAINED; @end @class NSString; @interface NSArray : NSObject - (NSUInteger)count; - (id)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))); ++ (instancetype)arrayWithObject:(id)anObject NS_RETURNS_NOT_RETAINED; ++ (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt NS_RETURNS_NOT_RETAINED; ++ (instancetype)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))) NS_RETURNS_NOT_RETAINED; - (id)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); - (id)initWithArray:(NSArray *)array; @end @interface NSArray (NSArrayCreation) + (instancetype)array; @@ -196,19 +196,19 @@ typedef double NSTimeInterval; @end typedef unsigned short unichar; @interface NSString : NSObject - (NSUInteger)length; -- (NSString *)stringByAppendingString:(NSString *)aString; +- (NSString *)stringByAppendingString:(NSString *)aString NS_RETURNS_NOT_RETAINED; - ( const char *)UTF8String; - (id)initWithUTF8String:(const char *)nullTerminatedCString; -+ (instancetype)stringWithUTF8String:(const char *)nullTerminatedCString; ++ (instancetype)stringWithUTF8String:(const char *)nullTerminatedCString NS_RETURNS_NOT_RETAINED; @end @class NSString, NSURL, NSError; @interface NSData : NSObject - (NSUInteger)length; -+ (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; -+ (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; ++ (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length NS_RETURNS_NOT_RETAINED; ++ (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b NS_RETURNS_NOT_RETAINED; @end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; @interface NSDictionary : NSObject - (NSUInteger)count; -+ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -+ (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt; ++ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys NS_RETURNS_NOT_RETAINED; ++ (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt NS_RETURNS_NOT_RETAINED; @end @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; - (void)setObject:(id)anObject forKey:(id)aKey; @@ -350,7 +350,7 @@ CF_IMPLICIT_BRIDGING_DISABLED @interface NSMutableArray : NSObject - (void)addObject:(id)object; -+ (instancetype)array; ++ (instancetype)array NS_RETURNS_NOT_RETAINED; @end // This is how NSMakeCollectable is declared in the OS X 10.8 headers. @@ -895,8 +895,8 @@ int RDar6320065_test() { //===----------------------------------------------------------------------===// @interface RDar6859457 : NSObject {} -- (NSString*) NoCopyString; -- (NSString*) noCopyString; +- (NSString*) NoCopyString NS_RETURNS_NOT_RETAINED; +- (NSString*) noCopyString NS_RETURNS_NOT_RETAINED; @end @implementation RDar6859457 @@ -1332,7 +1332,7 @@ void rdar7265711_b(RDar7265711 *x) { //===----------------------------------------------------------------------===// @interface NSCursor : NSObject -+ (NSCursor *)dragCopyCursor; ++ (NSCursor *)dragCopyCursor NS_RETURNS_NOT_RETAINED; @end void rdar7306898(void) { @@ -1368,7 +1368,7 @@ typedef NSString* MyStringTy; - (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning - (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning - (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning -- (NSString*) newString_auto NS_RETURNS_AUTORELEASED; // no-warning +- (NSString*) newString_auto NS_RETURNS_AUTORELEASED NS_RETURNS_NOT_RETAINED; // no-warning - (NSString*) newStringNoAttr; - (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to methods that return an Objective-C object}} - (id) pseudoInit NS_CONSUMES_SELF NS_RETURNS_RETAINED; @@ -1443,7 +1443,7 @@ void testattr4() { - (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED; - (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED; - (CFDateRef) newCFRetainedAsCFNoAttr CF_RETURNS_RETAINED; -- (NSDate*) alsoReturnsRetained; +- (NSDate*) alsoReturnsRetained NS_RETURNS_NOT_RETAINED; - (CFDateRef) alsoReturnsRetainedAsCF CF_RETURNS_NOT_RETAINED; - (NSDate*) returnsNSRetained NS_RETURNS_RETAINED; @end @@ -1579,7 +1579,7 @@ void r8272168() { // Test case for , which in the past triggered // a false positive. @interface RDar8356342 -- (NSDate*) rdar8356342:(NSDate *)inValue; +- (NSDate*) rdar8356342:(NSDate *)inValue NS_RETURNS_NOT_RETAINED; @end @implementation RDar8356342 @@ -1806,7 +1806,7 @@ int IOClose(void *context); @end @interface radar10973977 : NSObject -- (id)inputS; +- (id)inputS NS_RETURNS_NOT_RETAINED; - (void)reader; @end @@ -1825,7 +1825,7 @@ int IOClose(void *context); // Object escapes through a selector callback: radar://11398514 extern id NSApp; @interface MySheetController -- (id)inputS; +- (id)inputS NS_RETURNS_NOT_RETAINED; - (void)showDoSomethingSheetAction:(id)action; - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; @end @@ -2090,6 +2090,6 @@ CFAttributedStringRef CFAttributedCreate(void *CFObj CF_CONSUMED) CF_RETURNS_RET @interface Action @property(nonatomic) SEL action; -@property(nonatomic, unsafe_unretained) id target; +@property(nonatomic, unsafe_unretained) id target NS_RETURNS_NOT_RETAINED; @end