From: Steve Naroff Date: Wed, 11 Mar 2009 20:12:18 +0000 (+0000) Subject: Implement FIXME related to Implement class setter/getter... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=335c6808aabff7cb043ea02b72754fd580ce9712;p=clang Implement FIXME related to Implement class setter/getter for properties. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66689 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 95c0baae56..e5a917474f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1957,16 +1957,54 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, // Also must look for a getter name which uses property syntax. Selector Sel = PP.getSelectorTable().getNullarySelector(&Member); if (ObjCMethodDecl *MD = getCurMethodDecl()) { - ObjCMethodDecl *OMD; + ObjCInterfaceDecl *IFace = MD->getClassInterface(); + ObjCMethodDecl *Getter; // FIXME: need to also look locally in the implementation. - if ((OMD = MD->getClassInterface()->lookupClassMethod(Sel))) { + if ((Getter = IFace->lookupClassMethod(Sel))) { // Check the use of this method. - if (DiagnoseUseOfDecl(OMD, MemberLoc)) + if (DiagnoseUseOfDecl(Getter, MemberLoc)) return ExprError(); + } + // If we found a getter then this may be a valid dot-reference, we + // will look for the matching setter, in case it is needed. + Selector SetterSel = + SelectorTable::constructSetterName(PP.getIdentifierTable(), + PP.getSelectorTable(), &Member); + ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel); + if (!Setter) { + // If this reference is in an @implementation, also check for 'private' + // methods. + if (ObjCImplementationDecl *ImpDecl = + ObjCImplementations[IFace->getIdentifier()]) + Setter = ImpDecl->getInstanceMethod(SetterSel); + } + // Look through local category implementations associated with the class. + if (!Setter) { + for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) { + if (ObjCCategoryImpls[i]->getClassInterface() == IFace) + Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel); + } + } - return Owned(new (Context) ObjCMessageExpr(BaseExpr, Sel, - OMD->getResultType(), OMD, OpLoc, MemberLoc, NULL, 0)); + if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc)) + return ExprError(); + + if (Getter || Setter) { + QualType PType; + + if (Getter) + PType = Getter->getResultType(); + else { + for (ObjCMethodDecl::param_iterator PI = Setter->param_begin(), + E = Setter->param_end(); PI != E; ++PI) + PType = (*PI)->getType(); + } + // FIXME: we must check that the setter has property type. + return Owned(new (Context) ObjCKVCRefExpr(Getter, PType, + Setter, MemberLoc, BaseExpr)); } + return ExprError(Diag(MemberLoc, diag::err_property_not_found) + << &Member << BaseType); } } diff --git a/test/SemaObjC/newproperty-class-method-1.m b/test/SemaObjC/newproperty-class-method-1.m index 177cb3e8fc..155955c483 100644 --- a/test/SemaObjC/newproperty-class-method-1.m +++ b/test/SemaObjC/newproperty-class-method-1.m @@ -22,12 +22,9 @@ int _magicNumber = 0; + (void) classMeth { -#if 0 -// FIXME: implement. self.magicNumber = 10; if (self.magicNumber != 10) abort (); -#endif } @end