From 2ba62a72061b64ead359594672e85412024daa37 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 18 Sep 2013 17:22:25 +0000 Subject: [PATCH] ObjectiveC migrator: Infer property in the presense of methods annotated with attributes. // rdar://14987909 llvm-svn: 190947 --- clang/lib/ARCMigrate/ObjCMT.cpp | 37 +++++++++++++++++++---- clang/test/ARCMT/objcmt-property.m | 32 ++++++++++++++++++++ clang/test/ARCMT/objcmt-property.m.result | 36 ++++++++++++++++++++-- 3 files changed, 97 insertions(+), 8 deletions(-) diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp index 65a00331c5b6..08444442c76f 100644 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/clang/lib/ARCMigrate/ObjCMT.cpp @@ -721,6 +721,33 @@ static bool TypeIsInnerPointer(QualType T) { return true; } +static bool AttributesMatch(const Decl *Decl1, const Decl *Decl2) { + if (Decl1->hasAttrs() != Decl2->hasAttrs()) + return false; + + if (!Decl1->hasAttrs()) + return true; + + const AttrVec &Attrs1 = Decl1->getAttrs(); + const AttrVec &Attrs2 = Decl2->getAttrs(); + // This list is very small, so this need not be optimized. + for (unsigned i = 0, e = Attrs1.size(); i != e; i++) { + bool match = false; + for (unsigned j = 0, f = Attrs2.size(); j != f; j++) { + // Matching attribute kind only. We are not getting into + // details of the attributes. For all practical purposes + // this is sufficient. + if (Attrs1[i]->getKind() == Attrs2[j]->getKind()) { + match = true; + break; + } + } + if (!match) + return false; + } + return true; +} + bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx, ObjCContainerDecl *D, ObjCMethodDecl *Method) { @@ -731,9 +758,6 @@ bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx, QualType GRT = Method->getResultType(); if (GRT->isVoidType()) return false; - // FIXME. Don't know what todo with attributes, skip for now. - if (Method->hasAttrs()) - return false; Selector GetterSelector = Method->getSelector(); IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0); @@ -770,16 +794,17 @@ bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx, } if (SetterMethod) { - if (SetterMethod->isDeprecated()) + if (SetterMethod->isDeprecated() || + !AttributesMatch(Method, SetterMethod)) return false; + // Is this a valid setter, matching the target getter? QualType SRT = SetterMethod->getResultType(); if (!SRT->isVoidType()) return false; const ParmVarDecl *argDecl = *SetterMethod->param_begin(); QualType ArgType = argDecl->getType(); - if (!Ctx.hasSameUnqualifiedType(ArgType, GRT) || - SetterMethod->hasAttrs()) + if (!Ctx.hasSameUnqualifiedType(ArgType, GRT)) return false; edit::Commit commit(*Editor); rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit, diff --git a/clang/test/ARCMT/objcmt-property.m b/clang/test/ARCMT/objcmt-property.m index 5b11c4aa3a75..03aaaa0619e8 100644 --- a/clang/test/ARCMT/objcmt-property.m +++ b/clang/test/ARCMT/objcmt-property.m @@ -176,3 +176,35 @@ 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; + +@end diff --git a/clang/test/ARCMT/objcmt-property.m.result b/clang/test/ARCMT/objcmt-property.m.result index 39b0a8740f26..30bd028008fb 100644 --- a/clang/test/ARCMT/objcmt-property.m.result +++ b/clang/test/ARCMT/objcmt-property.m.result @@ -30,8 +30,8 @@ typedef char BOOL; - (NSString *) UnavailProp __attribute__((unavailable)); - (void) setUnavailProp : (NSString *)Val; -- (NSString *) UnavailProp1 __attribute__((unavailable)); -- (void) setUnavailProp1 : (NSString *)Val __attribute__((unavailable)); +@property(nonatomic, retain) NSString * UnavailProp1 __attribute__((unavailable)); + - (NSString *) UnavailProp2; - (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); @@ -176,3 +176,35 @@ 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; + +@property(nonatomic, retain) NSURL * appStoreReceiptURLX NS_AVAILABLE; + + +// Do not infer a property. +- (NSURL *)appStoreReceiptURLY ; +- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; + +@property(nonatomic, readonly) 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; + +@property(nonatomic, retain) id method1 ALIGNED NS_AVAILABLE; + + +@end