From: Fariborz Jahanian Date: Tue, 19 Oct 2010 23:47:54 +0000 (+0000) Subject: Do not rewrite new accessor if user has defined accessors. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec3683b3f33beda2449b4896b1a9548ab283e0e7;p=clang Do not rewrite new accessor if user has defined accessors. Fixes //rdar: // 8570020. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116882 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Rewrite/RewriteObjC.cpp b/lib/Rewrite/RewriteObjC.cpp index 7ae66f6238..0e81df72c5 100644 --- a/lib/Rewrite/RewriteObjC.cpp +++ b/lib/Rewrite/RewriteObjC.cpp @@ -767,59 +767,62 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, if (!OID) return; unsigned Attributes = PD->getPropertyAttributes(); - bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) && - (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | - ObjCPropertyDecl::OBJC_PR_copy)); - std::string Getr; - if (GenGetProperty && !objcGetPropertyDefined) { - objcGetPropertyDefined = true; - // FIXME. Is this attribute correct in all cases? - Getr = "\nextern \"C\" __declspec(dllimport) " - "id objc_getProperty(id, SEL, long, bool);\n"; - } - RewriteObjCMethodDecl(OID->getContainingInterface(), - PD->getGetterMethodDecl(), Getr); - Getr += "{ "; - // Synthesize an explicit cast to gain access to the ivar. - // See objc-act.c:objc_synthesize_new_getter() for details. - if (GenGetProperty) { - // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1) - Getr += "typedef "; - const FunctionType *FPRetType = 0; - RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr, - FPRetType); - Getr += " _TYPE"; - if (FPRetType) { - Getr += ")"; // close the precedence "scope" for "*". + if (!PD->getGetterMethodDecl()->isDefined()) { + bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) && + (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | + ObjCPropertyDecl::OBJC_PR_copy)); + std::string Getr; + if (GenGetProperty && !objcGetPropertyDefined) { + objcGetPropertyDefined = true; + // FIXME. Is this attribute correct in all cases? + Getr = "\nextern \"C\" __declspec(dllimport) " + "id objc_getProperty(id, SEL, long, bool);\n"; + } + RewriteObjCMethodDecl(OID->getContainingInterface(), + PD->getGetterMethodDecl(), Getr); + Getr += "{ "; + // Synthesize an explicit cast to gain access to the ivar. + // See objc-act.c:objc_synthesize_new_getter() for details. + if (GenGetProperty) { + // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1) + Getr += "typedef "; + const FunctionType *FPRetType = 0; + RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr, + FPRetType); + Getr += " _TYPE"; + if (FPRetType) { + Getr += ")"; // close the precedence "scope" for "*". - // Now, emit the argument types (if any). - if (const FunctionProtoType *FT = dyn_cast(FPRetType)){ - Getr += "("; - for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) { - if (i) Getr += ", "; - std::string ParamStr = FT->getArgType(i).getAsString( - Context->PrintingPolicy); - Getr += ParamStr; - } - if (FT->isVariadic()) { - if (FT->getNumArgs()) Getr += ", "; - Getr += "..."; - } - Getr += ")"; - } else - Getr += "()"; + // Now, emit the argument types (if any). + if (const FunctionProtoType *FT = dyn_cast(FPRetType)){ + Getr += "("; + for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) { + if (i) Getr += ", "; + std::string ParamStr = FT->getArgType(i).getAsString( + Context->PrintingPolicy); + Getr += ParamStr; + } + if (FT->isVariadic()) { + if (FT->getNumArgs()) Getr += ", "; + Getr += "..."; + } + Getr += ")"; + } else + Getr += "()"; + } + Getr += ";\n"; + Getr += "return (_TYPE)"; + Getr += "objc_getProperty(self, _cmd, "; + SynthesizeIvarOffsetComputation(OID, Getr); + Getr += ", 1)"; } - Getr += ";\n"; - Getr += "return (_TYPE)"; - Getr += "objc_getProperty(self, _cmd, "; - SynthesizeIvarOffsetComputation(OID, Getr); - Getr += ", 1)"; + else + Getr += "return " + getIvarAccessString(OID); + Getr += "; }"; + InsertText(onePastSemiLoc, Getr); } - else - Getr += "return " + getIvarAccessString(OID); - Getr += "; }"; - InsertText(onePastSemiLoc, Getr); - if (PD->isReadOnly()) + + if (PD->isReadOnly() || PD->getSetterMethodDecl()->isDefined()) return; // Generate the 'setter' function. @@ -3834,11 +3837,13 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, if (!PD) continue; if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) - InstanceMethods.push_back(Getter); + if (!Getter->isDefined()) + InstanceMethods.push_back(Getter); if (PD->isReadOnly()) continue; if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) - InstanceMethods.push_back(Setter); + if (!Setter->isDefined()) + InstanceMethods.push_back(Setter); } RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), true, "", IDecl->getName(), Result); diff --git a/test/Rewriter/rewrite-user-defined-accessors.mm b/test/Rewriter/rewrite-user-defined-accessors.mm new file mode 100644 index 0000000000..366e53b832 --- /dev/null +++ b/test/Rewriter/rewrite-user-defined-accessors.mm @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp +// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -Did="void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp +// rdar:// 8570020 + +@interface Foo { + Foo *foo; +} + +@property (retain, nonatomic) Foo *foo; + +@end + +@implementation Foo + +- (Foo *)foo { + if (!foo) { + foo = 0; + } + return foo; +} + + +- (void) setFoo : (Foo *) arg { + foo = arg; +} + +@synthesize foo; + +@end +