diff options
author | Steve Naroff <snaroff@apple.com> | 2009-03-11 20:12:18 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2009-03-11 20:12:18 +0000 |
commit | 28a531e0036c4881a7247950091c69ca5526af44 (patch) | |
tree | 32156d2aa66f42803a4294d7faa258668ac7b59f /clang/lib | |
parent | 605c7cab75e00172a4927f338eb770e8410025c8 (diff) | |
download | bcm5719-llvm-28a531e0036c4881a7247950091c69ca5526af44.tar.gz bcm5719-llvm-28a531e0036c4881a7247950091c69ca5526af44.zip |
Implement FIXME related to <rdar://problem/6496506> Implement class setter/getter for properties.
llvm-svn: 66689
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 95c0baae569..e5a917474fd 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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); } } |