From 1ab853d934daefee1806872a2d4a5f0fe0ff1939 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 12 Nov 2013 19:25:50 +0000 Subject: [PATCH] ObjectiveC migrator. Another alternative to "atomic" or "nonatomic" for properties is NS_NONATOMIC_IOSONLY. Use it if available. // rdar://15442742 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194503 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ARCMigrate/ObjCMT.cpp | 5 +- test/ARCMT/objcmt-ns-nonatomic-iosonly.m | 236 ++++++++++++++++++ .../objcmt-ns-nonatomic-iosonly.m.result | 209 ++++++++++++++++ 3 files changed, 449 insertions(+), 1 deletion(-) create mode 100644 test/ARCMT/objcmt-ns-nonatomic-iosonly.m create mode 100644 test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index f4461cabad..332fc96ef5 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -282,7 +282,10 @@ static void rewriteToObjCProperty(const ObjCMethodDecl *Getter, ASTContext &Context = NS.getASTContext(); bool LParenAdded = false; std::string PropertyString = "@property "; - if (!Atomic) { + if (Context.Idents.get("NS_NONATOMIC_IOSONLY").hasMacroDefinition()) { + PropertyString += "(NS_NONATOMIC_IOSONLY"; + LParenAdded = true; + } else if (!Atomic) { PropertyString += "(nonatomic"; LParenAdded = true; } diff --git a/test/ARCMT/objcmt-ns-nonatomic-iosonly.m b/test/ARCMT/objcmt-ns-nonatomic-iosonly.m new file mode 100644 index 0000000000..bd499058cb --- /dev/null +++ b/test/ARCMT/objcmt-ns-nonatomic-iosonly.m @@ -0,0 +1,236 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -objcmt-atomic-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION +#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) +#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER +#define DEPRECATED __attribute__((deprecated)) + +// rdar://15442742 +#if TARGET_OS_IPHONE + #define NS_NONATOMIC_IOSONLY nonatomic +#else + #define NS_NONATOMIC_IOSONLY atomic +#endif + +typedef char BOOL; +@class NSString; +@protocol NSCopying @end + +@interface NSObject +@end + +@interface NSDictionary : NSObject +@end + +@interface I : NSObject { + int ivarVal; +} +- (void) setWeakProp : (NSString *__weak)Val; +- (NSString *__weak) WeakProp; + +- (NSString *) StrongProp; +- (void) setStrongProp : (NSString *)Val; + +- (NSString *) UnavailProp __attribute__((unavailable)); +- (void) setUnavailProp : (NSString *)Val; + +- (NSString *) UnavailProp1 __attribute__((unavailable)); +- (void) setUnavailProp1 : (NSString *)Val __attribute__((unavailable)); + +- (NSString *) UnavailProp2; +- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); + +- (NSDictionary*) undoAction; +- (void) setUndoAction: (NSDictionary*)Arg; +@end + +@implementation I +@end + +@class NSArray; + +@interface MyClass2 { +@private + NSArray *_names1; + NSArray *_names2; + NSArray *_names3; + NSArray *_names4; +} +- (void)setNames1:(NSArray *)names; +- (void)setNames4:(__strong NSArray *)names; +- (void)setNames3:(__strong NSArray *)names; +- (void)setNames2:(NSArray *)names; +- (NSArray *) names2; +- (NSArray *)names3; +- (__strong NSArray *)names4; +- (NSArray *) names1; +@end + +// Properties that contain the name "delegate" or "dataSource", +// or have exact name "target" have unsafe_unretained attribute. +@interface NSInvocation +- (id)target; +- (void)setTarget:(id)target; + +- (id) dataSource; + +- (id)xxxdelegateYYY; +- (void)setXxxdelegateYYY:(id)delegate; + +- (void)setDataSource:(id)source; + +- (id)MYtarget; +- (void)setMYtarget: (id)target; + +- (id)targetX; +- (void)setTargetX: (id)t; + +- (int)value; +- (void)setValue: (int)val; + +-(BOOL) isContinuous; +-(void) setContinuous:(BOOL)value; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +- (int) Length; +- (id) object; ++ (double) D; +- (void *)JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); +- (BOOL)isIgnoringInteractionEvents; + +- (NSString *)getStringValue; +- (BOOL)getCounterValue; +- (void)setStringValue:(NSString *)stringValue AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (NSDictionary *)getns_dixtionary; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +- (BOOL) getM; +- (BOOL) getMA; +- (BOOL) getALL; +- (BOOL) getMANY; +- (BOOL) getSome; +@end + + +@interface NSInvocation(CAT) +- (id)target; +- (void)setTarget:(id)target; + +- (id) dataSource; + +- (id)xxxdelegateYYY; +- (void)setXxxdelegateYYY:(id)delegate; + +- (void)setDataSource:(id)source; + +- (id)MYtarget; +- (void)setMYtarget: (id)target; + +- (id)targetX; +- (void)setTargetX: (id)t; + +- (int)value; +- (void)setValue: (int)val; + +-(BOOL) isContinuous; +-(void) setContinuous:(BOOL)value; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +- (int) Length; +- (id) object; ++ (double) D; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +- (BOOL) getM; +- (BOOL) getMA; +- (BOOL) getALL; +- (BOOL) getMANY; +- (BOOL) getSome; +@end + +DEPRECATED +@interface I_DEP +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; +@end + +@interface AnotherOne +- (BOOL) isinValid DEPRECATED; +- (void) setInValid : (BOOL) arg; +- (id)MYtarget; +- (void)setMYtarget: (id)target DEPRECATED; +- (BOOL) getM DEPRECATED; + +- (id)xxxdelegateYYY DEPRECATED; +- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; +@end + +// rdar://14987909 +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) +#define NORETURN __attribute__((noreturn)) +#define ALIGNED __attribute__((aligned(16))) + +@interface NSURL +// Do not infer a property. +- (NSURL *)appStoreReceiptURL NS_AVAILABLE; +- (void) setAppStoreReceiptURL : (NSURL *)object; + +- (NSURL *)appStoreReceiptURLX NS_AVAILABLE; +- (void) setAppStoreReceiptURLX : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (NSURL *)appStoreReceiptURLY ; +- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; + +- (id)OkToInfer NS_AVAILABLE; + +// Do not infer a property. +- (NSURL *)appStoreReceiptURLZ ; +- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (id) t1 NORETURN NS_AVAILABLE; +- (void) setT1 : (id) arg NS_AVAILABLE; + +- (id)method1 ALIGNED NS_AVAILABLE; +- (void) setMethod1 : (id) object NS_AVAILABLE ALIGNED; + +- (NSURL *)init; // No Change ++ (id)alloc; // No Change + +- (BOOL)is1stClass; // Not a valid property +- (BOOL)isClass; // This is a valid property 'class' is not a keyword in ObjC +- (BOOL)isDouble; // Not a valid property + +@end + +// rdar://15082818 +@class NSMutableDictionary; + +@interface NSArray +- (id (^)(id, NSArray *, NSMutableDictionary *)) expressionBlock; +- (id (^)(id, NSArray *, NSMutableDictionary *)) MyBlock; +- (void) setMyBlock : (id (^)(id, NSArray *, NSMutableDictionary *)) bl; +- (id (*)(id, NSArray *, NSMutableDictionary *)) expressionFuncptr; +- (id (*)(id, NSArray *, NSMutableDictionary *)) MyFuncptr; +- (void) setMyFuncptr : (id (*)(id, NSArray *, NSMutableDictionary *)) bl; +@end diff --git a/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result b/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result new file mode 100644 index 0000000000..53eb922835 --- /dev/null +++ b/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result @@ -0,0 +1,209 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -objcmt-atomic-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION +#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) +#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER +#define DEPRECATED __attribute__((deprecated)) + +// rdar://15442742 +#if TARGET_OS_IPHONE + #define NS_NONATOMIC_IOSONLY nonatomic +#else + #define NS_NONATOMIC_IOSONLY atomic +#endif + +typedef char BOOL; +@class NSString; +@protocol NSCopying @end + +@interface NSObject +@end + +@interface NSDictionary : NSObject +@end + +@interface I : NSObject { + int ivarVal; +} +@property (NS_NONATOMIC_IOSONLY, weak) NSString *WeakProp; + +@property (NS_NONATOMIC_IOSONLY, retain) NSString *StrongProp; + +@property (NS_NONATOMIC_IOSONLY, retain) NSString *UnavailProp __attribute__((unavailable)); +- (void) setUnavailProp : (NSString *)Val; + +@property (NS_NONATOMIC_IOSONLY, retain) NSString *UnavailProp1 __attribute__((unavailable)); + +@property (NS_NONATOMIC_IOSONLY, retain) NSString *UnavailProp2; +- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); + +@property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *undoAction; +@end + +@implementation I +@end + +@class NSArray; + +@interface MyClass2 { +@private + NSArray *_names1; + NSArray *_names2; + NSArray *_names3; + NSArray *_names4; +} +@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names2; +@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names3; +@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names4; +@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names1; +@end + +// Properties that contain the name "delegate" or "dataSource", +// or have exact name "target" have unsafe_unretained attribute. +@interface NSInvocation +@property (NS_NONATOMIC_IOSONLY, assign) id target; + +@property (NS_NONATOMIC_IOSONLY, assign) id dataSource; + +@property (NS_NONATOMIC_IOSONLY, assign) id xxxdelegateYYY; + + +@property (NS_NONATOMIC_IOSONLY, retain) id MYtarget; + +@property (NS_NONATOMIC_IOSONLY, retain) id targetX; + +@property (NS_NONATOMIC_IOSONLY) int value; + +@property (NS_NONATOMIC_IOSONLY, getter=isContinuous) BOOL continuous; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +@property (NS_NONATOMIC_IOSONLY, getter=isinValid, readonly) BOOL inValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +@property (NS_NONATOMIC_IOSONLY, readonly) int Length; +@property (NS_NONATOMIC_IOSONLY, readonly) id object; ++ (double) D; +@property (NS_NONATOMIC_IOSONLY, readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); +@property (NS_NONATOMIC_IOSONLY, getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents; + +@property (NS_NONATOMIC_IOSONLY, getter=getStringValue, retain) NSString *stringValue; +@property (NS_NONATOMIC_IOSONLY, getter=getCounterValue, readonly) BOOL counterValue; +@property (NS_NONATOMIC_IOSONLY, getter=getns_dixtionary, readonly) NSDictionary *ns_dixtionary; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +@property (NS_NONATOMIC_IOSONLY, getter=getM, readonly) BOOL m; +@property (NS_NONATOMIC_IOSONLY, getter=getMA, readonly) BOOL MA; +@property (NS_NONATOMIC_IOSONLY, getter=getALL, readonly) BOOL ALL; +@property (NS_NONATOMIC_IOSONLY, getter=getMANY, readonly) BOOL MANY; +@property (NS_NONATOMIC_IOSONLY, getter=getSome, readonly) BOOL some; +@end + + +@interface NSInvocation(CAT) +@property (NS_NONATOMIC_IOSONLY, assign) id target; + +@property (NS_NONATOMIC_IOSONLY, assign) id dataSource; + +@property (NS_NONATOMIC_IOSONLY, assign) id xxxdelegateYYY; + + +@property (NS_NONATOMIC_IOSONLY, retain) id MYtarget; + +@property (NS_NONATOMIC_IOSONLY, retain) id targetX; + +@property (NS_NONATOMIC_IOSONLY) int value; + +@property (NS_NONATOMIC_IOSONLY, getter=isContinuous) BOOL continuous; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +@property (NS_NONATOMIC_IOSONLY, getter=isinValid, readonly) BOOL inValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +@property (NS_NONATOMIC_IOSONLY, readonly) int Length; +@property (NS_NONATOMIC_IOSONLY, readonly) id object; ++ (double) D; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +@property (NS_NONATOMIC_IOSONLY, getter=getM, readonly) BOOL m; +@property (NS_NONATOMIC_IOSONLY, getter=getMA, readonly) BOOL MA; +@property (NS_NONATOMIC_IOSONLY, getter=getALL, readonly) BOOL ALL; +@property (NS_NONATOMIC_IOSONLY, getter=getMANY, readonly) BOOL MANY; +@property (NS_NONATOMIC_IOSONLY, getter=getSome, readonly) BOOL some; +@end + +DEPRECATED +@interface I_DEP +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; +@end + +@interface AnotherOne +- (BOOL) isinValid DEPRECATED; +- (void) setInValid : (BOOL) arg; +- (id)MYtarget; +- (void)setMYtarget: (id)target DEPRECATED; +- (BOOL) getM DEPRECATED; + +- (id)xxxdelegateYYY DEPRECATED; +- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; +@end + +// rdar://14987909 +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) +#define NORETURN __attribute__((noreturn)) +#define ALIGNED __attribute__((aligned(16))) + +@interface NSURL +// Do not infer a property. +@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURL NS_AVAILABLE; +- (void) setAppStoreReceiptURL : (NSURL *)object; + +@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURLX NS_AVAILABLE; + +// Do not infer a property. +@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURLY ; +- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; + +@property (NS_NONATOMIC_IOSONLY, readonly) id OkToInfer NS_AVAILABLE; + +// Do not infer a property. +@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURLZ ; +- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (id) t1 NORETURN NS_AVAILABLE; +- (void) setT1 : (id) arg NS_AVAILABLE; + +@property (NS_NONATOMIC_IOSONLY, retain) id method1 ALIGNED NS_AVAILABLE; + +- (NSURL *)init; // No Change ++ (id)alloc; // No Change + +- (BOOL)is1stClass; // Not a valid property +@property (NS_NONATOMIC_IOSONLY, getter=isClass, readonly) BOOL class; // This is a valid property 'class' is not a keyword in ObjC +- (BOOL)isDouble; // Not a valid property + +@end + +// rdar://15082818 +@class NSMutableDictionary; + +@interface NSArray +@property (NS_NONATOMIC_IOSONLY, readonly) id (^expressionBlock)(id, NSArray *, NSMutableDictionary *); +@property (NS_NONATOMIC_IOSONLY, copy) id (^MyBlock)(id, NSArray *, NSMutableDictionary *); +@property (NS_NONATOMIC_IOSONLY, readonly) id (*expressionFuncptr)(id, NSArray *, NSMutableDictionary *); +@property (NS_NONATOMIC_IOSONLY) id (*MyFuncptr)(id, NSArray *, NSMutableDictionary *); +@end -- 2.40.0