aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2009-03-11 20:12:18 +0000
committerSteve Naroff <snaroff@apple.com>2009-03-11 20:12:18 +0000
commit335c6808aabff7cb043ea02b72754fd580ce9712 (patch)
treeaeaca1cb4709284ef8c6ceb5793597aa384e1ee3
parent3cf538d5c49bbebac1afa6f4a5010e3d877440bb (diff)
Implement FIXME related to <rdar://problem/6496506> Implement class setter/getter for properties.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66689 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExpr.cpp48
-rw-r--r--test/SemaObjC/newproperty-class-method-1.m3
2 files changed, 43 insertions, 8 deletions
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