diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/DeclObjC.h | 2 | ||||
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Edit/RewriteObjCFoundationAPI.cpp | 25 | ||||
-rw-r--r-- | clang/test/ARCMT/objcmt-property.m | 10 | ||||
-rw-r--r-- | clang/test/ARCMT/objcmt-property.m.result | 22 |
5 files changed, 57 insertions, 13 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index e4ca61a5c07..1e7a0d7a9a9 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -1136,6 +1136,8 @@ public: return lookupInstanceVariable(IVarName, ClassDeclared); } + ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name); + // Lookup a method. First, we search locally. If a method isn't // found, we search referenced protocols and class categories. ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 3895a520857..c15f01debaf 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -441,6 +441,17 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass( return NULL; } +ObjCProtocolDecl * +ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) { + for (ObjCInterfaceDecl::all_protocol_iterator P = + all_referenced_protocol_begin(), PE = all_referenced_protocol_end(); + P != PE; ++P) + if ((*P)->lookupProtocolNamed(Name)) + return (*P); + ObjCInterfaceDecl *SuperClass = getSuperClass(); + return SuperClass ? SuperClass->lookupNestedProtocol(Name) : NULL; +} + /// lookupMethod - This method returns an instance/class method by looking in /// the class, its categories, and its super classes (using a linear search). /// When argument category "C" is specified, any implicit method found diff --git a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp index e257a0b6f1c..8d24003d942 100644 --- a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp +++ b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp @@ -358,23 +358,38 @@ bool edit::rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg, bool edit::rewriteToObjCProperty(const ObjCMethodDecl *Getter, const ObjCMethodDecl *Setter, const NSAPI &NS, Commit &commit) { + ASTContext &Context = NS.getASTContext(); std::string PropertyString = "@property"; const ParmVarDecl *argDecl = *Setter->param_begin(); - QualType ArgType = argDecl->getType(); + QualType ArgType = Context.getCanonicalType(argDecl->getType()); Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime(); if (ArgType->isObjCRetainableType() && propertyLifetime == Qualifiers::OCL_Strong) { - PropertyString += "(copy)"; + if (const ObjCObjectPointerType *ObjPtrTy = + ArgType->getAs<ObjCObjectPointerType>()) { + ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface(); + if (IDecl && + IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying"))) + PropertyString += "(copy)"; + } } else if (propertyLifetime == Qualifiers::OCL_Weak) + // TODO. More precise determination of 'weak' attribute requires + // looking into setter's implementation for backing weak ivar. PropertyString += "(weak)"; else PropertyString += "(unsafe_unretained)"; - - QualType PropQT = Getter->getResultType(); + + // strip off any ARC lifetime qualifier. + QualType CanResultTy = Context.getCanonicalType(Getter->getResultType()); + if (CanResultTy.getQualifiers().hasObjCLifetime()) { + Qualifiers Qs = CanResultTy.getQualifiers(); + Qs.removeObjCLifetime(); + CanResultTy = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs); + } PropertyString += " "; - PropertyString += PropQT.getAsString(NS.getASTContext().getPrintingPolicy()); + PropertyString += CanResultTy.getAsString(Context.getPrintingPolicy()); PropertyString += " "; PropertyString += Getter->getNameAsString(); commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(), diff --git a/clang/test/ARCMT/objcmt-property.m b/clang/test/ARCMT/objcmt-property.m index 1f0bcdd7353..ca1b504dcbd 100644 --- a/clang/test/ARCMT/objcmt-property.m +++ b/clang/test/ARCMT/objcmt-property.m @@ -4,7 +4,13 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties %s.result @class NSString; -@interface NSObject @end +@protocol NSCopying @end + +@interface NSObject <NSCopying> +@end + +@interface NSDictionary : NSObject +@end @interface I : NSObject { int ivarVal; @@ -24,6 +30,8 @@ - (NSString *) UnavailProp2; - (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); +- (NSDictionary*) undoAction; +- (void) setUndoAction: (NSDictionary*)Arg; @end @implementation I diff --git a/clang/test/ARCMT/objcmt-property.m.result b/clang/test/ARCMT/objcmt-property.m.result index 11912d950a2..2bcae864a0c 100644 --- a/clang/test/ARCMT/objcmt-property.m.result +++ b/clang/test/ARCMT/objcmt-property.m.result @@ -4,15 +4,21 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties %s.result @class NSString; -@interface NSObject @end +@protocol NSCopying @end + +@interface NSObject <NSCopying> +@end + +@interface NSDictionary : NSObject +@end @interface I : NSObject { int ivarVal; } -@property(weak) NSString *__weak WeakProp; +@property(weak) NSString * WeakProp; -@property(copy) NSString * StrongProp; +@property NSString * StrongProp; - (NSString *) UnavailProp __attribute__((unavailable)); @@ -24,6 +30,8 @@ - (NSString *) UnavailProp2; - (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); +@property(copy) NSDictionary * undoAction; + @end @implementation I @@ -42,8 +50,8 @@ -@property(copy) NSArray * names2; -@property(copy) NSArray * names3; -@property(copy) NSArray *__strong names4; -@property(copy) NSArray * names1; +@property NSArray * names2; +@property NSArray * names3; +@property NSArray * names4; +@property NSArray * names1; @end |