From: Fariborz Jahanian Date: Thu, 19 Mar 2009 18:15:34 +0000 (+0000) Subject: When looking for property name (or getter method) in a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2ce1be03e25eed3f5bf7762367b7cdb7221b0a51;p=clang When looking for property name (or getter method) in a dot-syntax expression after earching the list of protocols in the qualified-id, must keep searching the protocol list of each of the protocols in the list. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67314 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index e43d4b8027..c06f1cfad7 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1697,6 +1697,51 @@ CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc, return VT; // should never get here (a typedef type should always be found). } +static Decl *FindGetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDecl, + IdentifierInfo &Member, + const Selector &Sel) { + + if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(&Member)) + return PD; + if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel)) + return OMD; + + for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(), + E = PDecl->protocol_end(); I != E; ++I) { + if (Decl *D = FindGetterNameDeclFromProtocolList(*I, Member, Sel)) + return D; + } + return 0; +} + +static Decl *FindGetterNameDecl(const ObjCQualifiedIdType *QIdTy, + IdentifierInfo &Member, + const Selector &Sel) { + // Check protocols on qualified interfaces. + Decl *GDecl = 0; + for (ObjCQualifiedIdType::qual_iterator I = QIdTy->qual_begin(), + E = QIdTy->qual_end(); I != E; ++I) { + if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) { + GDecl = PD; + break; + } + // Also must look for a getter name which uses property syntax. + if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Sel)) { + GDecl = OMD; + break; + } + } + if (!GDecl) { + for (ObjCQualifiedIdType::qual_iterator I = QIdTy->qual_begin(), + E = QIdTy->qual_end(); I != E; ++I) { + // Search in the protocol-qualifier list of current protocol. + GDecl = FindGetterNameDeclFromProtocolList(*I, Member, Sel); + if (GDecl) + return GDecl; + } + } + return GDecl; +} Action::OwningExprResult Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, @@ -1968,25 +2013,25 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, const ObjCQualifiedIdType *QIdTy; if (OpKind == tok::period && (QIdTy = BaseType->getAsObjCQualifiedIdType())) { // Check protocols on qualified interfaces. - for (ObjCQualifiedIdType::qual_iterator I = QIdTy->qual_begin(), - E = QIdTy->qual_end(); I != E; ++I) { - if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) { + Selector Sel = PP.getSelectorTable().getNullarySelector(&Member); + if (Decl *PMDecl = FindGetterNameDecl(QIdTy, Member, Sel)) { + if (ObjCPropertyDecl *PD = dyn_cast(PMDecl)) { // Check the use of this declaration if (DiagnoseUseOfDecl(PD, MemberLoc)) return ExprError(); - + return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc, BaseExpr)); } - // Also must look for a getter name which uses property syntax. - Selector Sel = PP.getSelectorTable().getNullarySelector(&Member); - if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Sel)) { + if (ObjCMethodDecl *OMD = dyn_cast(PMDecl)) { // Check the use of this method. if (DiagnoseUseOfDecl(OMD, MemberLoc)) return ExprError(); - + return Owned(new (Context) ObjCMessageExpr(BaseExpr, Sel, - OMD->getResultType(), OMD, OpLoc, MemberLoc, NULL, 0)); + OMD->getResultType(), + OMD, OpLoc, MemberLoc, + NULL, 0)); } } diff --git a/test/SemaObjC/access-property-getter.m b/test/SemaObjC/access-property-getter.m new file mode 100644 index 0000000000..903f53c25e --- /dev/null +++ b/test/SemaObjC/access-property-getter.m @@ -0,0 +1,35 @@ +// RUN: clang -verify %s + +@protocol NSObject +- (oneway void)release; +@end + +@protocol XCOutputStreams +@end + + +@interface XCWorkQueueCommandInvocation +{ + id _outputStream; +} +@end + +@interface XCWorkQueueCommandSubprocessInvocation : XCWorkQueueCommandInvocation +@end + +@interface XCWorkQueueCommandLocalSubprocessInvocation : XCWorkQueueCommandSubprocessInvocation +@end + +@interface XCWorkQueueCommandDistributedSubprocessInvocation : XCWorkQueueCommandSubprocessInvocation +@end + +@interface XCWorkQueueCommandCacheFetchInvocation : XCWorkQueueCommandSubprocessInvocation + +@end + +@implementation XCWorkQueueCommandCacheFetchInvocation +- (id)harvestPredictivelyProcessedOutputFiles +{ + _outputStream.release; +} +@end